@mparticle/web-sdk 3.24.0 → 3.25.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/mparticle.common.js +1 -1
- package/dist/mparticle.esm.js +1 -1
- package/dist/mparticle.js +332 -79
- package/dist/types/src/buttonTracking/buttonClickEvent.d.ts +4 -1
- package/dist/types/src/buttonTracking/buttonDescription.d.ts +8 -1
- package/dist/types/src/buttonTracking/buttonTracker.d.ts +6 -0
- package/dist/types/src/buttonTracking/checkoutIntent.d.ts +6 -1
- package/dist/types/src/buttonTracking/controls.d.ts +2 -1
- package/dist/types/src/constants.d.ts +1 -0
- package/dist/types/src/cookieConsentManager.d.ts +17 -3
- package/dist/types/src/roktLauncherOptions.d.ts +1 -0
- package/dist/types/src/roktManager.d.ts +10 -1
- package/dist/types/src/store.d.ts +1 -0
- package/package.json +1 -1
- package/src/buttonTracking/buttonClickEvent.ts +61 -18
- package/src/buttonTracking/buttonDescription.ts +104 -11
- package/src/buttonTracking/buttonTracker.ts +112 -15
- package/src/buttonTracking/checkoutIntent.ts +75 -23
- package/src/buttonTracking/controls.ts +10 -6
- package/src/constants.ts +1 -0
- package/src/cookieConsentManager.ts +23 -3
- package/src/cookieSyncManager.ts +11 -3
- package/src/mp-instance.ts +26 -8
- package/src/roktLauncherOptions.ts +1 -0
- package/src/roktManager.ts +47 -7
- package/src/store.ts +3 -0
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.25.0";
|
|
208
208
|
|
|
209
209
|
var Constants = {
|
|
210
210
|
sdkVersion: version,
|
|
@@ -379,7 +379,8 @@ var mParticle = (function () {
|
|
|
379
379
|
CaptureIntegrationSpecificIdsV2: 'captureIntegrationSpecificIds.V2',
|
|
380
380
|
AstBackgroundEvents: 'astBackgroundEvents',
|
|
381
381
|
AutoLogPageView: 'autoLogPageView',
|
|
382
|
-
AutoButtonTracking: 'autoButtonTracking'
|
|
382
|
+
AutoButtonTracking: 'autoButtonTracking',
|
|
383
|
+
AutoLinkTracking: 'autoLinkTracking'
|
|
383
384
|
},
|
|
384
385
|
DefaultInstance: 'default_instance',
|
|
385
386
|
CCPAPurpose: 'data_sale_opt_out',
|
|
@@ -5349,9 +5350,13 @@ var mParticle = (function () {
|
|
|
5349
5350
|
if (requiresConsent && mpidIsNotInCookies) {
|
|
5350
5351
|
return;
|
|
5351
5352
|
}
|
|
5352
|
-
// For Rokt, block cookie sync
|
|
5353
|
-
|
|
5354
|
-
|
|
5353
|
+
// For Rokt, block cookie sync under the noTargeting or doNotShareOrSell privacy flag,
|
|
5354
|
+
// or when the browser sends Global Privacy Control
|
|
5355
|
+
if (moduleId === PARTNER_MODULE_IDS.Rokt) {
|
|
5356
|
+
var nav = typeof navigator === 'undefined' ? undefined : navigator;
|
|
5357
|
+
if (mpInstance._CookieConsentManager.getNoTargeting() || mpInstance._CookieConsentManager.getDoNotShareOrSell() || !!nav && nav.globalPrivacyControl === true) {
|
|
5358
|
+
return;
|
|
5359
|
+
}
|
|
5355
5360
|
}
|
|
5356
5361
|
var isEnabledForUserConsent = mpInstance._Consent.isEnabledForUserConsent;
|
|
5357
5362
|
if (!isEnabledForUserConsent(filteringConsentRuleValues, mpInstance.Identity.getCurrentUser())) {
|
|
@@ -6545,7 +6550,8 @@ var mParticle = (function () {
|
|
|
6545
6550
|
CaptureIntegrationSpecificIdsV2 = _a.CaptureIntegrationSpecificIdsV2,
|
|
6546
6551
|
AstBackgroundEvents = _a.AstBackgroundEvents,
|
|
6547
6552
|
AutoLogPageView = _a.AutoLogPageView,
|
|
6548
|
-
AutoButtonTracking = _a.AutoButtonTracking
|
|
6553
|
+
AutoButtonTracking = _a.AutoButtonTracking,
|
|
6554
|
+
AutoLinkTracking = _a.AutoLinkTracking;
|
|
6549
6555
|
if (!config.flags) {
|
|
6550
6556
|
return {};
|
|
6551
6557
|
}
|
|
@@ -6563,6 +6569,7 @@ var mParticle = (function () {
|
|
|
6563
6569
|
flags[AstBackgroundEvents] = config.flags[AstBackgroundEvents] === 'True';
|
|
6564
6570
|
flags[AutoLogPageView] = config.flags[AutoLogPageView] === 'True';
|
|
6565
6571
|
flags[AutoButtonTracking] = config.flags[AutoButtonTracking] === 'True';
|
|
6572
|
+
flags[AutoLinkTracking] = config.flags[AutoLinkTracking] === 'True';
|
|
6566
6573
|
return flags;
|
|
6567
6574
|
}
|
|
6568
6575
|
function processBaseUrls(config, flags, apiKey) {
|
|
@@ -11035,21 +11042,27 @@ var mParticle = (function () {
|
|
|
11035
11042
|
RoktManager.prototype.setAutoButtonClicksForwarded = function (forwarded) {
|
|
11036
11043
|
this.autoButtonClicksForwarded = forwarded;
|
|
11037
11044
|
};
|
|
11045
|
+
// noTargeting (which noDeviceId implies), doNotShareOrSell or Global Privacy
|
|
11046
|
+
// Control. Unlike noFunctional, these also stop auto button and link clicks
|
|
11047
|
+
// from being logged.
|
|
11048
|
+
RoktManager.prototype.hasTargetingOptOut = function () {
|
|
11049
|
+
var options = this.launcherOptions || {};
|
|
11050
|
+
if (options.noTargeting || options.doNotShareOrSell) {
|
|
11051
|
+
return true;
|
|
11052
|
+
}
|
|
11053
|
+
var nav = typeof navigator === 'undefined' ? undefined : navigator;
|
|
11054
|
+
return !!nav && nav.globalPrivacyControl === true;
|
|
11055
|
+
};
|
|
11038
11056
|
// Checkout intent is off unless the flag is on, and under opt-out, any Rokt
|
|
11039
11057
|
// privacy launcher option, Global Privacy Control, or a Rokt connection that
|
|
11040
11058
|
// does not receive auto button clicks.
|
|
11041
11059
|
RoktManager.prototype.isCheckoutIntentSuppressed = function () {
|
|
11042
|
-
var _a, _b;
|
|
11060
|
+
var _a, _b, _c;
|
|
11043
11061
|
var flags = (_b = (_a = this.store) === null || _a === void 0 ? void 0 : _a.SDKConfig) === null || _b === void 0 ? void 0 : _b.flags;
|
|
11044
11062
|
if (!flags || flags[Constants.FeatureFlags.AutoButtonTracking] !== true || !this.store.isEnabled || !this.autoButtonClicksForwarded) {
|
|
11045
11063
|
return true;
|
|
11046
11064
|
}
|
|
11047
|
-
|
|
11048
|
-
if (options.noFunctional || options.noTargeting || options.doNotShareOrSell) {
|
|
11049
|
-
return true;
|
|
11050
|
-
}
|
|
11051
|
-
var nav = typeof navigator === 'undefined' ? undefined : navigator;
|
|
11052
|
-
return !!nav && nav.globalPrivacyControl === true;
|
|
11065
|
+
return !!((_c = this.launcherOptions) === null || _c === void 0 ? void 0 : _c.noFunctional) || this.hasTargetingOptOut();
|
|
11053
11066
|
};
|
|
11054
11067
|
// True when the kit can wait for the shopper's confirm click: signals are not
|
|
11055
11068
|
// suppressed and the browser exposes the composed path the detector reads.
|
|
@@ -11091,6 +11104,23 @@ var mParticle = (function () {
|
|
|
11091
11104
|
RoktManager.prototype.discardCheckoutIntents = function () {
|
|
11092
11105
|
this.pendingCheckoutIntents = [];
|
|
11093
11106
|
};
|
|
11107
|
+
// Under the same gates as checkout intent. A pick made before a kit
|
|
11108
|
+
// attaches is not kept: the shopper is still choosing, and the next pick
|
|
11109
|
+
// replaces it.
|
|
11110
|
+
RoktManager.prototype.notifyPaymentPick = function (signal) {
|
|
11111
|
+
var _a;
|
|
11112
|
+
if (this.isCheckoutIntentSuppressed()) {
|
|
11113
|
+
return;
|
|
11114
|
+
}
|
|
11115
|
+
var kit = this.kit;
|
|
11116
|
+
try {
|
|
11117
|
+
if (kit && isFunction(kit.onPaymentPick)) {
|
|
11118
|
+
kit.onPaymentPick(signal);
|
|
11119
|
+
}
|
|
11120
|
+
} catch (e) {
|
|
11121
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.error("RoktManager: Error in onPaymentPick: ".concat(getErrorMessage(e)));
|
|
11122
|
+
}
|
|
11123
|
+
};
|
|
11094
11124
|
// Replays recent buffered signals raised on the current page, oldest first.
|
|
11095
11125
|
RoktManager.prototype.flushCheckoutIntents = function () {
|
|
11096
11126
|
var _this = this;
|
|
@@ -11646,12 +11676,12 @@ var mParticle = (function () {
|
|
|
11646
11676
|
}();
|
|
11647
11677
|
|
|
11648
11678
|
/**
|
|
11649
|
-
* CookieConsentManager handles storage and access of consent flags (noFunctional, noTargeting
|
|
11650
|
-
* that are passed via launcherOptions during SDK initialization.
|
|
11679
|
+
* CookieConsentManager handles storage and access of consent flags (noFunctional, noTargeting,
|
|
11680
|
+
* doNotShareOrSell) that are passed via launcherOptions during SDK initialization.
|
|
11651
11681
|
*
|
|
11652
11682
|
* These flags allow Rokt integration to respect user privacy choices.
|
|
11653
11683
|
*
|
|
11654
|
-
* Default behavior:
|
|
11684
|
+
* Default behavior: All flags default to false, meaning all features are allowed
|
|
11655
11685
|
* unless explicitly opted out by the user.
|
|
11656
11686
|
*/
|
|
11657
11687
|
var CookieConsentManager = /** @class */function () {
|
|
@@ -11659,7 +11689,8 @@ var mParticle = (function () {
|
|
|
11659
11689
|
this.flags = flags;
|
|
11660
11690
|
this.flags = {
|
|
11661
11691
|
noFunctional: flags.noFunctional === true,
|
|
11662
|
-
noTargeting: flags.noTargeting === true
|
|
11692
|
+
noTargeting: flags.noTargeting === true,
|
|
11693
|
+
doNotShareOrSell: flags.doNotShareOrSell === true
|
|
11663
11694
|
};
|
|
11664
11695
|
}
|
|
11665
11696
|
/**
|
|
@@ -11676,6 +11707,13 @@ var mParticle = (function () {
|
|
|
11676
11707
|
CookieConsentManager.prototype.getNoFunctional = function () {
|
|
11677
11708
|
return this.flags.noFunctional;
|
|
11678
11709
|
};
|
|
11710
|
+
/**
|
|
11711
|
+
* Returns true if the user has opted out of the sale or sharing of their data.
|
|
11712
|
+
* Sharing is allowed when doNotShareOrSell is false (default).
|
|
11713
|
+
*/
|
|
11714
|
+
CookieConsentManager.prototype.getDoNotShareOrSell = function () {
|
|
11715
|
+
return this.flags.doNotShareOrSell;
|
|
11716
|
+
};
|
|
11679
11717
|
CookieConsentManager.prototype.syncNoTargetingAttribute = function (user) {
|
|
11680
11718
|
if (!user) return;
|
|
11681
11719
|
if (this.flags.noTargeting) {
|
|
@@ -11733,19 +11771,20 @@ var mParticle = (function () {
|
|
|
11733
11771
|
var AUTO_BUTTON_ATTRIBUTE = 'is_auto_button_click';
|
|
11734
11772
|
// Specific enough not to merge with a customer's own 'Button Click' event.
|
|
11735
11773
|
var BUTTON_CLICK_EVENT_NAME = 'Auto Button Click';
|
|
11736
|
-
//
|
|
11737
|
-
|
|
11738
|
-
|
|
11739
|
-
|
|
11740
|
-
|
|
11741
|
-
|
|
11774
|
+
// Marks an automatically logged click on a link that leaves the page.
|
|
11775
|
+
var AUTO_LINK_ATTRIBUTE = 'is_auto_link_click';
|
|
11776
|
+
var LINK_CLICK_EVENT_NAME = 'Auto Link Click';
|
|
11777
|
+
// The attributes both click events carry, with the page fields that auto page
|
|
11778
|
+
// views carry. No intent: classifying clicks is left to whoever reads the data.
|
|
11779
|
+
var clickAttributes = function clickAttributes(click, pathname) {
|
|
11780
|
+
var data = {
|
|
11742
11781
|
label_source: click.labelSource,
|
|
11743
11782
|
element: click.element,
|
|
11744
11783
|
type: click.type,
|
|
11745
11784
|
path: pathname,
|
|
11746
11785
|
hostname: window.location.hostname
|
|
11747
|
-
}
|
|
11748
|
-
// Optional fields are left out when the
|
|
11786
|
+
};
|
|
11787
|
+
// Optional fields are left out when the control has no safe value for them.
|
|
11749
11788
|
var optional = {
|
|
11750
11789
|
label: click.label,
|
|
11751
11790
|
aria_label: click.ariaLabel,
|
|
@@ -11759,8 +11798,8 @@ var mParticle = (function () {
|
|
|
11759
11798
|
link_domain: click.linkDomain,
|
|
11760
11799
|
file_extension: click.fileExtension
|
|
11761
11800
|
};
|
|
11762
|
-
for (var _i = 0,
|
|
11763
|
-
var key =
|
|
11801
|
+
for (var _i = 0, _a = Object.keys(optional); _i < _a.length; _i++) {
|
|
11802
|
+
var key = _a[_i];
|
|
11764
11803
|
if (optional[key]) {
|
|
11765
11804
|
data[key] = optional[key];
|
|
11766
11805
|
}
|
|
@@ -11768,6 +11807,12 @@ var mParticle = (function () {
|
|
|
11768
11807
|
if (click.checked !== undefined) {
|
|
11769
11808
|
data.checked = click.checked;
|
|
11770
11809
|
}
|
|
11810
|
+
return data;
|
|
11811
|
+
};
|
|
11812
|
+
// One custom event per button click, logged like logLink() with the auto marker.
|
|
11813
|
+
var buildButtonClickEvent = function buildButtonClickEvent(click, pathname) {
|
|
11814
|
+
var data = clickAttributes(click, pathname);
|
|
11815
|
+
data[AUTO_BUTTON_ATTRIBUTE] = true;
|
|
11771
11816
|
return {
|
|
11772
11817
|
messageType: MessageType$1.PageEvent,
|
|
11773
11818
|
name: BUTTON_CLICK_EVENT_NAME,
|
|
@@ -11775,28 +11820,52 @@ var mParticle = (function () {
|
|
|
11775
11820
|
eventType: EventType.Other
|
|
11776
11821
|
};
|
|
11777
11822
|
};
|
|
11823
|
+
// One custom event per click on a link that leaves the page. Typed Other, not
|
|
11824
|
+
// Navigation, so no kit reads it as a page change. A plain link to another page
|
|
11825
|
+
// of the site goes without its text, which can name the shopper ("Hi, Jane");
|
|
11826
|
+
// a button or wallet acting as a link keeps its name.
|
|
11827
|
+
var buildLinkClickEvent = function buildLinkClickEvent(click, pathname) {
|
|
11828
|
+
var data = clickAttributes(click.linkType === 'internal' && click.element === 'link' ? __assign(__assign({}, click), {
|
|
11829
|
+
label: undefined,
|
|
11830
|
+
labelSource: 'none',
|
|
11831
|
+
ariaLabel: undefined
|
|
11832
|
+
}) : click, pathname);
|
|
11833
|
+
data[AUTO_LINK_ATTRIBUTE] = true;
|
|
11834
|
+
return {
|
|
11835
|
+
messageType: MessageType$1.PageEvent,
|
|
11836
|
+
name: LINK_CLICK_EVENT_NAME,
|
|
11837
|
+
data: data,
|
|
11838
|
+
eventType: EventType.Other
|
|
11839
|
+
};
|
|
11840
|
+
};
|
|
11778
11841
|
// Every attribute buildButtonClickEvent can set apart from the marker and the
|
|
11779
11842
|
// hostname, which is the same on every click on this page. A spec checks the
|
|
11780
11843
|
// two stay in step.
|
|
11781
11844
|
var CLICK_ATTRIBUTES = ['label_source', 'element', 'type', 'path', 'label', 'aria_label', 'icon', 'element_id', 'element_name', 'test_id', 'controls', 'form', 'link_type', 'link_domain', 'file_extension', 'checked'];
|
|
11782
|
-
// Which check keeps some or all auto button clicks
|
|
11783
|
-
// when the kit receives every one. A forwarding
|
|
11784
|
-
// value differs between clicks lets some through and
|
|
11785
|
-
// check goes through isEventForwarded on its own, so
|
|
11786
|
-
// it does for each click.
|
|
11787
|
-
var getButtonClickBlocker = function getButtonClickBlocker(forwarder, kitBlocker) {
|
|
11788
|
-
|
|
11845
|
+
// Which check keeps some or all auto button clicks, or auto link clicks with
|
|
11846
|
+
// `link`, from a kit, or undefined when the kit receives every one. A forwarding
|
|
11847
|
+
// rule on an attribute whose value differs between clicks lets some through and
|
|
11848
|
+
// not others. Each other check goes through isEventForwarded on its own, so
|
|
11849
|
+
// together they decide as it does for each click.
|
|
11850
|
+
var getButtonClickBlocker = function getButtonClickBlocker(forwarder, kitBlocker, link) {
|
|
11851
|
+
if (link === void 0) {
|
|
11852
|
+
link = false;
|
|
11853
|
+
}
|
|
11789
11854
|
var rule = forwarder.filteringEventAttributeValue;
|
|
11790
11855
|
if (rule && rule.eventAttributeValue && CLICK_ATTRIBUTES.some(function (name) {
|
|
11791
11856
|
return KitFilterHelper.hashAttributeConditionalForwarding(name) === rule.eventAttributeName;
|
|
11792
11857
|
})) {
|
|
11793
11858
|
return 'forwarding rule';
|
|
11794
11859
|
}
|
|
11860
|
+
var attributes = {
|
|
11861
|
+
hostname: window.location.hostname
|
|
11862
|
+
};
|
|
11863
|
+
attributes[link ? AUTO_LINK_ATTRIBUTE : AUTO_BUTTON_ATTRIBUTE] = true;
|
|
11795
11864
|
var click = {
|
|
11796
|
-
EventName: BUTTON_CLICK_EVENT_NAME,
|
|
11865
|
+
EventName: link ? LINK_CLICK_EVENT_NAME : BUTTON_CLICK_EVENT_NAME,
|
|
11797
11866
|
EventCategory: EventType.Other,
|
|
11798
11867
|
EventDataType: MessageType$1.PageEvent,
|
|
11799
|
-
EventAttributes:
|
|
11868
|
+
EventAttributes: attributes
|
|
11800
11869
|
};
|
|
11801
11870
|
var checks = [['data plan', {}], ['forwarding rule', {
|
|
11802
11871
|
filteringEventAttributeValue: rule
|
|
@@ -12020,9 +12089,13 @@ var mParticle = (function () {
|
|
|
12020
12089
|
return control;
|
|
12021
12090
|
}
|
|
12022
12091
|
// Text that may hold what a shopper typed or what the page opted out: form
|
|
12023
|
-
// fields, editable regions, and anything under data-mp-no-track.
|
|
12024
|
-
|
|
12025
|
-
|
|
12092
|
+
// fields, editable regions, and anything under data-mp-no-track. `own` is a
|
|
12093
|
+
// box the element labels, which holds no typing of its own.
|
|
12094
|
+
function isUnsafeTextSource(element, own) {
|
|
12095
|
+
var inside = 'input, select, textarea, [data-mp-no-track], ' + EDITABLE;
|
|
12096
|
+
return element.matches('input, select, textarea, option, optgroup, datalist, ' + EDITABLE) || (own ? Array.from(element.querySelectorAll(inside)).some(function (found) {
|
|
12097
|
+
return found !== own;
|
|
12098
|
+
}) : !!element.querySelector(inside)) || hasComposedAncestor(element, 'select, datalist, textarea, [data-mp-no-track], ' + EDITABLE);
|
|
12026
12099
|
}
|
|
12027
12100
|
|
|
12028
12101
|
// Masks a button label before it is logged. Button text can carry personal data,
|
|
@@ -12363,8 +12436,8 @@ var mParticle = (function () {
|
|
|
12363
12436
|
return tag === 'button' || tag === 'input' ? control.type : 'button';
|
|
12364
12437
|
}
|
|
12365
12438
|
// Reads the link's own resolved URL parts, never its full href: only the hostname of
|
|
12366
|
-
// a link that leaves the site and the extension of a file it downloads travel.
|
|
12367
|
-
//
|
|
12439
|
+
// a link that leaves the site and the extension of a file it downloads travel.
|
|
12440
|
+
// mailto:, tel: and other schemes give undefined.
|
|
12368
12441
|
function describeLink(link) {
|
|
12369
12442
|
var href = (link.getAttribute('href') || '').trim();
|
|
12370
12443
|
if (!href || href.charAt(0) === '#') {
|
|
@@ -12401,7 +12474,14 @@ var mParticle = (function () {
|
|
|
12401
12474
|
}
|
|
12402
12475
|
return link.pathname === window.location.pathname && link.search === window.location.search ? {
|
|
12403
12476
|
type: 'same_page'
|
|
12404
|
-
} :
|
|
12477
|
+
} : {
|
|
12478
|
+
type: 'internal'
|
|
12479
|
+
};
|
|
12480
|
+
}
|
|
12481
|
+
// Whether a described click is on a link that leaves the page, logged as a link
|
|
12482
|
+
// click rather than a button click.
|
|
12483
|
+
function isLinkClick(click) {
|
|
12484
|
+
return !!click.linkType && click.linkType !== 'same_page';
|
|
12405
12485
|
}
|
|
12406
12486
|
// Checkboxes and radios, and the roles that act as them. A role can list
|
|
12407
12487
|
// fallbacks, so any of its tokens counts.
|
|
@@ -12411,6 +12491,9 @@ var mParticle = (function () {
|
|
|
12411
12491
|
var box = element instanceof HTMLLabelElement ? element.control : element;
|
|
12412
12492
|
return box && box.matches(CHOICE) ? box : null;
|
|
12413
12493
|
}
|
|
12494
|
+
function isRadio(choice) {
|
|
12495
|
+
return choice instanceof HTMLInputElement ? choice.type === 'radio' : !!choice && choice.matches(RADIO_ROLE);
|
|
12496
|
+
}
|
|
12414
12497
|
// The box a click on this control picks. One the click passed through below
|
|
12415
12498
|
// the control comes first: querySelector can't reach a slotted box, a box in a
|
|
12416
12499
|
// shadow root or the box of a label inside the control, and a row can hold
|
|
@@ -12429,8 +12512,9 @@ var mParticle = (function () {
|
|
|
12429
12512
|
}
|
|
12430
12513
|
return boxOf(control) || control.querySelector(CHOICE);
|
|
12431
12514
|
}
|
|
12432
|
-
// Describes a clicked control for auto button tracking. A link
|
|
12433
|
-
//
|
|
12515
|
+
// Describes a clicked control for auto button and link tracking. A link carries its
|
|
12516
|
+
// link type, and one to another scheme is skipped. A role="button" anchor carries one
|
|
12517
|
+
// only when it leaves the page; otherwise it stays a plain button.
|
|
12434
12518
|
function describeButtonClick(control, path) {
|
|
12435
12519
|
if (path === void 0) {
|
|
12436
12520
|
path = [];
|
|
@@ -12441,6 +12525,11 @@ var mParticle = (function () {
|
|
|
12441
12525
|
if (!link) {
|
|
12442
12526
|
return undefined;
|
|
12443
12527
|
}
|
|
12528
|
+
} else if (control.matches('a[href]')) {
|
|
12529
|
+
link = describeLink(control);
|
|
12530
|
+
if (link && link.type === 'same_page') {
|
|
12531
|
+
link = undefined;
|
|
12532
|
+
}
|
|
12444
12533
|
}
|
|
12445
12534
|
var element = elementKind(control);
|
|
12446
12535
|
var box = control instanceof HTMLInputElement && (control.type === 'checkbox' || control.type === 'radio') ? control : undefined;
|
|
@@ -12454,7 +12543,7 @@ var mParticle = (function () {
|
|
|
12454
12543
|
// radio's id, test id and the panel it opens name the option picked, so
|
|
12455
12544
|
// only the name of its input, the question, goes with it. A wrapper's own
|
|
12456
12545
|
// name, or a role radio's, can name the option instead.
|
|
12457
|
-
var radio = choice
|
|
12546
|
+
var radio = isRadio(choice);
|
|
12458
12547
|
var named = !radio ? control : choice instanceof HTMLInputElement ? choice : null;
|
|
12459
12548
|
var name = choice ? undefined : accessibleName(control);
|
|
12460
12549
|
var label = name ? maskLabel(name.raw) : undefined;
|
|
@@ -12480,6 +12569,54 @@ var mParticle = (function () {
|
|
|
12480
12569
|
checked: box ? box.checked : undefined
|
|
12481
12570
|
};
|
|
12482
12571
|
}
|
|
12572
|
+
// A question about payment, read from the names its author gave it, so
|
|
12573
|
+
// "checkout[payment_gateway]", "paymentMethod" and "tender_type" all count and
|
|
12574
|
+
// "payee" does not. A radio's input name is its question; its group or
|
|
12575
|
+
// fieldset speaks only for a radio with no name, as a role radio usually is.
|
|
12576
|
+
var PAYMENT_QUESTION = /(?:^| )(?:pay|payment\w*|tenders?|gateways?)(?: |$)/;
|
|
12577
|
+
var QUESTION_GROUP = '[role="radiogroup"], fieldset';
|
|
12578
|
+
function isPaymentQuestion(radio) {
|
|
12579
|
+
var name = radio.getAttribute('name');
|
|
12580
|
+
var group = name ? null : radio.closest(QUESTION_GROUP);
|
|
12581
|
+
var question = group ? [group.getAttribute('id'), group.getAttribute('name'), group.getAttribute('aria-label')] : [name];
|
|
12582
|
+
return question.some(function (words) {
|
|
12583
|
+
return PAYMENT_QUESTION.test(nameWords(words));
|
|
12584
|
+
});
|
|
12585
|
+
}
|
|
12586
|
+
// What names a payment option: the radio's accessible name, the text and
|
|
12587
|
+
// image of each label, and its hand-written ids, text masked like a label.
|
|
12588
|
+
function optionNames(radio) {
|
|
12589
|
+
var names = [maskLabel(accessibleName(radio).raw)];
|
|
12590
|
+
var labels = radio instanceof HTMLInputElement && radio.labels ? Array.from(radio.labels).slice(0, 2) : [];
|
|
12591
|
+
labels.forEach(function (label) {
|
|
12592
|
+
if (isShown(label) && !isUnsafeTextSource(label, radio)) {
|
|
12593
|
+
names.push(maskLabel(renderedText(label)));
|
|
12594
|
+
names.push(maskLabel(shownImageAlt(label)));
|
|
12595
|
+
}
|
|
12596
|
+
});
|
|
12597
|
+
names.push(stableIdentifier(radio.getAttribute('id')), firstIdentifier(radio, TEST_ID_ATTRIBUTES));
|
|
12598
|
+
return names.filter(function (name, index) {
|
|
12599
|
+
return !!name && names.indexOf(name) === index;
|
|
12600
|
+
});
|
|
12601
|
+
}
|
|
12602
|
+
function describePaymentChoice(control, path) {
|
|
12603
|
+
if (path === void 0) {
|
|
12604
|
+
path = [];
|
|
12605
|
+
}
|
|
12606
|
+
var choice = choiceOf(control, path);
|
|
12607
|
+
if (!isRadio(choice) || hasComposedAncestor(choice, '[data-mp-no-track]') || !isPaymentQuestion(choice)) {
|
|
12608
|
+
return undefined;
|
|
12609
|
+
}
|
|
12610
|
+
var names = optionNames(choice);
|
|
12611
|
+
return names.length ? {
|
|
12612
|
+
radio: choice,
|
|
12613
|
+
names: names
|
|
12614
|
+
} : undefined;
|
|
12615
|
+
}
|
|
12616
|
+
// Read once the page has handled the click, which may have cancelled it.
|
|
12617
|
+
function isPicked(radio) {
|
|
12618
|
+
return radio instanceof HTMLInputElement ? radio.checked : radio.getAttribute('aria-checked') === 'true';
|
|
12619
|
+
}
|
|
12483
12620
|
|
|
12484
12621
|
var checkoutPath = /(?:^|\/)(?:checkouts?|payment|order|kasse|paiement|commander?|pago)(?:\/|$)/i;
|
|
12485
12622
|
// English look-alikes are whole words; the other languages stay substring
|
|
@@ -12495,9 +12632,11 @@ var mParticle = (function () {
|
|
|
12495
12632
|
var routeGatedCommits = new RegExp('^(?:buy now|purchase|jetzt kaufen|kaufen|commander|(?:passer|valider) (?:la |ma )?commande|finalizar (?:la |mi )?compra|' + 'comprar ahora|acquista ora|nu kopen|\u4ECA\u3059\u3050\u8CFC\u5165|\u8CFC\u5165\u3059\u308B|\u3053\u306E\u5185\u5BB9\u3067\u7533\u3057\u8FBC\u3080)$');
|
|
12496
12633
|
var steps = new RegExp('^(?:' + ["(?:let's |lets |go to |proceed to |secure )?(?:check ?out|checkout)(?: now| securely| as guest)?", '(?:continue|proceed) to (?:payment|review|billing|shipping|delivery|order review)|review (?:my |your )?order', 'guest checkout|(?:pay|continue|check ?out) (?:with|by) (?:card|credit card|debit card|credit or debit card)', 'zur kasse|zur kasse gehen|auschecken|weiter zur zahlung', 'passer \u00E0 la caisse|continuer vers le paiement|proc\u00E9der au paiement', 'ir a caja|continuar al pago|tramitar pedido', "procedi al checkout|procedi all'acquisto|procedi al pagamento|vai alla cassa", 'afrekenen|verder naar betalen|doorgaan naar betalen', '\u30EC\u30B8\u306B\u9032\u3080|\u3054?(?:\u8CFC\u5165|\u6CE8\u6587)\u624B\u7D9A\u304D(?:\u3078|\u306B)(?:\u9032\u3080)?|\u304A?\u652F\u6255\u3044(?:\u3078|\u306B)\u9032\u3080|(?:\u3054\u6CE8\u6587\u5185\u5BB9\u306E)?\u78BA\u8A8D\u753B\u9762\u3078(?:\u9032\u3080)?'].join('|') + ')$');
|
|
12497
12634
|
var CART_NOUN = '(?:(?:my|your|the) )?(?:shopping )?(?:cart|bag|basket)';
|
|
12498
|
-
// "Add to bag"
|
|
12499
|
-
|
|
12500
|
-
|
|
12635
|
+
// "Add to bag" and "Add 2 to cart": a click that puts something in the cart.
|
|
12636
|
+
var addToCartLabels = new RegExp('^add(?: [^ ]+){0,5} to ' + CART_NOUN + '$');
|
|
12637
|
+
// "View cart", "Shopping bag", "Bag", and a count badge such as "1 item in bag",
|
|
12638
|
+
// which reads "item in bag" once digits are stripped: a click that opens the cart.
|
|
12639
|
+
var openCartLabels = new RegExp('^(?:(?:(?:view|open|go to) )?' + CART_NOUN + '(?: items?)?' + '|items? in ' + CART_NOUN + ')$');
|
|
12501
12640
|
var WALLET_NAMES = 'apple pay|google pay|paypal|venmo|amazon pay|shop pay|klarna|afterpay|clearpay|cash app(?: pay)?|affirm|sezzle|samsung pay';
|
|
12502
12641
|
var WALLET_VERBS = 'pay|buy|purchase|order|book|donate|subscribe|check ?out|checkout|express checkout|continue|proceed|' + 'complete purchase|place (?:my |your )?order';
|
|
12503
12642
|
// "Pay with Klarna", "Buy with GPay", "Continue to PayPal".
|
|
@@ -12505,14 +12644,27 @@ var mParticle = (function () {
|
|
|
12505
12644
|
// A wallet's own name on a button: "PayPal", "Klarna checkout", "Apple Pay logo".
|
|
12506
12645
|
var walletBrands = new RegExp('^(?:' + WALLET_NAMES + ')(?: (?:checkout|check out|express(?: checkout)?|express pay|buy now|pay now|pay|now)' + '| (?:logo|icon|mark|button)(?: (?:logo|icon|mark|button))*)?$');
|
|
12507
12646
|
// Exact HTTPS hosts of hosted wallet button frames.
|
|
12508
|
-
var
|
|
12647
|
+
var walletFrameFamilies = {
|
|
12648
|
+
'pay.google.com': 'google_pay',
|
|
12649
|
+
'applepay.cdn-apple.com': 'apple_pay',
|
|
12650
|
+
'payments.amazon.com': 'amazon_pay',
|
|
12651
|
+
'pay.shopify.com': 'shop_pay'
|
|
12652
|
+
};
|
|
12509
12653
|
// PayPal serves its buttons and its card fields and pay-later messages from
|
|
12510
12654
|
// the same hosts; only the button frames are wallet taps.
|
|
12511
12655
|
var paypalFrameHosts = new Set(['www.paypal.com', 'www.sandbox.paypal.com']);
|
|
12512
12656
|
var PAYPAL_BUTTON_FRAME = /^\/smart\/(?:buttons|menu)(?:\/|$)/;
|
|
12657
|
+
var PAYPAL_CARD_FRAME = /^\/smart\/card-fields?(?:\/|$)/;
|
|
12658
|
+
// PayPal's JS SDK, used directly or wrapped by a processor, leaves its frames
|
|
12659
|
+
// without a src and names them __zoid__paypal_<component>__ instead.
|
|
12660
|
+
var PAYPAL_SDK_FRAME = /^__zoid__paypal_/;
|
|
12661
|
+
var PAYPAL_SDK_BUTTON_FRAME = /^__zoid__paypal_(?:buttons|menu)__/;
|
|
12513
12662
|
// Stripe's quick-pay button frames; its other frames are card and form fields.
|
|
12514
12663
|
var STRIPE_WALLET_FRAME = /\/elements-inner-(?:payment-request|express-checkout)-/;
|
|
12664
|
+
var STRIPE_CARD_FRAME = /\/elements-inner-card\b/;
|
|
12515
12665
|
// Hosted card-entry and fingerprint frames: focus there is typing card details.
|
|
12666
|
+
// Some of these hosts also serve gift card and bank account fields, so none
|
|
12667
|
+
// names a family.
|
|
12516
12668
|
var CARD_FRAME_DOMAINS = ['adyen.com', 'braintreegateway.com', 'cybersource.com', 'squarecdn.com', 'checkout.com'];
|
|
12517
12669
|
// Keep these classes ASCII-only in source bytes to avoid mojibake parse failures
|
|
12518
12670
|
// when a host page forces non-UTF-8 decoding before JavaScript parse.
|
|
@@ -12574,11 +12726,19 @@ var mParticle = (function () {
|
|
|
12574
12726
|
});
|
|
12575
12727
|
}
|
|
12576
12728
|
// A cart button is often a bare icon, so its title names it when nothing else
|
|
12577
|
-
// does. Only the cart rule reads the title.
|
|
12729
|
+
// does. Only the cart rule reads the title. Opening the cart counts only for a
|
|
12730
|
+
// control that opens it on the page, such as a flyout: one that leads to the cart
|
|
12731
|
+
// page unloads before a call made on the click can return.
|
|
12578
12732
|
function isCartControl(control, cores) {
|
|
12579
12733
|
var title = cores.length ? undefined : normalize(control.getAttribute('title'));
|
|
12580
|
-
|
|
12581
|
-
|
|
12734
|
+
var texts = title ? [coreLabel(title)] : cores;
|
|
12735
|
+
if (texts.some(function (text) {
|
|
12736
|
+
return addToCartLabels.test(text);
|
|
12737
|
+
})) {
|
|
12738
|
+
return true;
|
|
12739
|
+
}
|
|
12740
|
+
return (control.hasAttribute('aria-expanded') || control.hasAttribute('aria-haspopup')) && texts.some(function (text) {
|
|
12741
|
+
return openCartLabels.test(text);
|
|
12582
12742
|
});
|
|
12583
12743
|
}
|
|
12584
12744
|
// "Buy now" and "Purchase" count only on a checkout route, and never on a plain
|
|
@@ -12593,8 +12753,8 @@ var mParticle = (function () {
|
|
|
12593
12753
|
// pickers, toggles and pay-later messages never count; a vendor's own wallet
|
|
12594
12754
|
// button counts before any label rule; a confirm label on any source counts
|
|
12595
12755
|
// before the look-alike exclusions veto; then a wallet-named control, wallet
|
|
12596
|
-
// phrases and steps.
|
|
12597
|
-
// those do.
|
|
12756
|
+
// phrases and steps. An add-to-cart label, links included, or a control that
|
|
12757
|
+
// opens the cart on the page counts only where none of those do.
|
|
12598
12758
|
function classifyIntent(control, pathname) {
|
|
12599
12759
|
var vendor = vendorButtonKind(control);
|
|
12600
12760
|
if (vendor === 'none') {
|
|
@@ -12668,30 +12828,66 @@ var mParticle = (function () {
|
|
|
12668
12828
|
return host === domain || host.length > domain.length && host.slice(host.length - domain.length - 1) === '.' + domain;
|
|
12669
12829
|
}
|
|
12670
12830
|
// Focus moving into a visible hosted wallet button counts as a wallet click;
|
|
12671
|
-
// focus into hosted card fields or messages is only a frame.
|
|
12672
|
-
|
|
12831
|
+
// focus into hosted card fields or messages is only a frame. A family comes
|
|
12832
|
+
// only from a frame that can draw no other method: PayPal's button frame also
|
|
12833
|
+
// draws Pay Later, Venmo and its card form, Stripe's quick-pay frame draws
|
|
12834
|
+
// Apple Pay or Google Pay by browser, and its payment form holds several.
|
|
12835
|
+
function classifyPaymentFrame(target, win) {
|
|
12673
12836
|
if (win.document.visibilityState !== 'visible' || !(target instanceof HTMLIFrameElement)) {
|
|
12674
12837
|
return undefined;
|
|
12675
12838
|
}
|
|
12676
12839
|
if (isRoktElement(target) || hasComposedAncestor(target, '[data-mp-no-track]')) {
|
|
12677
12840
|
return undefined;
|
|
12678
12841
|
}
|
|
12842
|
+
// A frame that has its own src is judged by that address, never by its name.
|
|
12843
|
+
if ((!target.src || target.src === 'about:blank') && PAYPAL_SDK_FRAME.test(target.name)) {
|
|
12844
|
+
return PAYPAL_SDK_BUTTON_FRAME.test(target.name) ? {
|
|
12845
|
+
kind: 'wallet'
|
|
12846
|
+
} : {
|
|
12847
|
+
kind: 'frame'
|
|
12848
|
+
};
|
|
12849
|
+
}
|
|
12679
12850
|
try {
|
|
12680
12851
|
var url = new URL(target.src);
|
|
12681
12852
|
var host_1 = url.protocol === 'https:' ? url.hostname : '';
|
|
12682
12853
|
if (paypalFrameHosts.has(host_1)) {
|
|
12683
|
-
|
|
12854
|
+
if (PAYPAL_BUTTON_FRAME.test(url.pathname)) {
|
|
12855
|
+
return {
|
|
12856
|
+
kind: 'wallet'
|
|
12857
|
+
};
|
|
12858
|
+
}
|
|
12859
|
+
return PAYPAL_CARD_FRAME.test(url.pathname) ? {
|
|
12860
|
+
kind: 'frame',
|
|
12861
|
+
family: 'card'
|
|
12862
|
+
} : {
|
|
12863
|
+
kind: 'frame'
|
|
12864
|
+
};
|
|
12684
12865
|
}
|
|
12685
|
-
if (
|
|
12686
|
-
return
|
|
12866
|
+
if (Object.prototype.hasOwnProperty.call(walletFrameFamilies, host_1)) {
|
|
12867
|
+
return {
|
|
12868
|
+
kind: 'wallet',
|
|
12869
|
+
family: walletFrameFamilies[host_1]
|
|
12870
|
+
};
|
|
12687
12871
|
}
|
|
12688
12872
|
if (host_1 === 'js.stripe.com') {
|
|
12689
|
-
|
|
12873
|
+
if (STRIPE_WALLET_FRAME.test(url.pathname)) {
|
|
12874
|
+
return {
|
|
12875
|
+
kind: 'wallet'
|
|
12876
|
+
};
|
|
12877
|
+
}
|
|
12878
|
+
return STRIPE_CARD_FRAME.test(url.pathname) ? {
|
|
12879
|
+
kind: 'frame',
|
|
12880
|
+
family: 'card'
|
|
12881
|
+
} : {
|
|
12882
|
+
kind: 'frame'
|
|
12883
|
+
};
|
|
12690
12884
|
}
|
|
12691
12885
|
if (CARD_FRAME_DOMAINS.some(function (domain) {
|
|
12692
12886
|
return isOnDomain(host_1, domain);
|
|
12693
12887
|
})) {
|
|
12694
|
-
return
|
|
12888
|
+
return {
|
|
12889
|
+
kind: 'frame'
|
|
12890
|
+
};
|
|
12695
12891
|
}
|
|
12696
12892
|
} catch (e) {
|
|
12697
12893
|
// An unparseable frame src is not a wallet frame.
|
|
@@ -12808,13 +13004,16 @@ var mParticle = (function () {
|
|
|
12808
13004
|
var PASSIVE = {
|
|
12809
13005
|
passive: true
|
|
12810
13006
|
};
|
|
12811
|
-
// Logs
|
|
12812
|
-
// Rokt kit as a frozen {kind, t, source, pathname}. Submits and wallet frame focus feed the kit only
|
|
13007
|
+
// 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}. Submits and wallet frame focus feed the kit only,
|
|
13009
|
+
// and so do payment picks: a payment radio's option names, or the payment family of a focused frame.
|
|
12813
13010
|
var ButtonTracker = /** @class */function () {
|
|
12814
13011
|
function ButtonTracker(mpInstance) {
|
|
12815
13012
|
var _this = this;
|
|
12816
13013
|
this.active = false;
|
|
12817
13014
|
this.hasRoktKit = false;
|
|
13015
|
+
this.logButtons = false;
|
|
13016
|
+
this.logLinks = false;
|
|
12818
13017
|
// Bumped on reset so classification queued before it is dropped.
|
|
12819
13018
|
this.generation = 0;
|
|
12820
13019
|
this.lastCommitClick = -Infinity;
|
|
@@ -12888,7 +13087,9 @@ var mParticle = (function () {
|
|
|
12888
13087
|
this.teardown();
|
|
12889
13088
|
}
|
|
12890
13089
|
this.hasRoktKit = options.hasRoktKit;
|
|
12891
|
-
|
|
13090
|
+
this.logButtons = options.logButtons;
|
|
13091
|
+
this.logLinks = options.logLinks;
|
|
13092
|
+
if ((!(this.logButtons || this.logLinks) || !this.eventsEnabled()) && this.isKitSuppressed()) {
|
|
12892
13093
|
this.log('opted out, not starting');
|
|
12893
13094
|
return;
|
|
12894
13095
|
}
|
|
@@ -12989,7 +13190,7 @@ var mParticle = (function () {
|
|
|
12989
13190
|
return;
|
|
12990
13191
|
}
|
|
12991
13192
|
var layer = event.type;
|
|
12992
|
-
var logsEvents = layer === 'click' && this.eventsEnabled();
|
|
13193
|
+
var logsEvents = layer === 'click' && (this.logButtons || this.logLinks) && this.eventsEnabled() && !this.hasTargetingOptOut();
|
|
12993
13194
|
var signalsKit = !this.isKitSuppressed();
|
|
12994
13195
|
if (!logsEvents && !signalsKit) {
|
|
12995
13196
|
return;
|
|
@@ -13001,9 +13202,12 @@ var mParticle = (function () {
|
|
|
13001
13202
|
// button that disables or relabels itself is seen as it was clicked.
|
|
13002
13203
|
// Logging and the kit hand-off wait for the next paint.
|
|
13003
13204
|
var click;
|
|
13205
|
+
var asLink = false;
|
|
13004
13206
|
var box;
|
|
13005
13207
|
var kind;
|
|
13006
13208
|
var source;
|
|
13209
|
+
var choice;
|
|
13210
|
+
var family;
|
|
13007
13211
|
var unconfirmedCommit = false;
|
|
13008
13212
|
if (layer === 'click') {
|
|
13009
13213
|
// The composed path is only populated during dispatch.
|
|
@@ -13011,7 +13215,18 @@ var mParticle = (function () {
|
|
|
13011
13215
|
var excluded = isExcludedPath(path);
|
|
13012
13216
|
var control = excluded ? undefined : findControl(path, true);
|
|
13013
13217
|
if (control) {
|
|
13014
|
-
|
|
13218
|
+
// With links alone, only an anchor can be logged.
|
|
13219
|
+
click = logsEvents && (this.logButtons || control.matches('a[href]')) ? describeButtonClick(control, path) : undefined;
|
|
13220
|
+
if (click) {
|
|
13221
|
+
asLink = this.logLinks && isLinkClick(click);
|
|
13222
|
+
// Without link tracking, a link that leaves the page stays a
|
|
13223
|
+
// button click, except a plain link to another page of the
|
|
13224
|
+
// site, which button tracking never logged.
|
|
13225
|
+
var asButton = this.logButtons && !asLink && !(click.linkType === 'internal' && control.matches('a[href]:not([role="button"])'));
|
|
13226
|
+
if (!asLink && !asButton) {
|
|
13227
|
+
click = undefined;
|
|
13228
|
+
}
|
|
13229
|
+
}
|
|
13015
13230
|
if (click && click.checked !== undefined) {
|
|
13016
13231
|
box = control;
|
|
13017
13232
|
}
|
|
@@ -13019,6 +13234,7 @@ var mParticle = (function () {
|
|
|
13019
13234
|
var intent = signalsKit ? classifyIntent(control, pathname) : undefined;
|
|
13020
13235
|
kind = intent ? intent.kind : undefined;
|
|
13021
13236
|
source = intent ? intent.source : undefined;
|
|
13237
|
+
choice = signalsKit ? describePaymentChoice(control, path) : undefined;
|
|
13022
13238
|
}
|
|
13023
13239
|
this.lastClick = {
|
|
13024
13240
|
t: t,
|
|
@@ -13050,7 +13266,9 @@ var mParticle = (function () {
|
|
|
13050
13266
|
if (layer === 'blur') {
|
|
13051
13267
|
// Read after the blur settles: some browsers have not moved
|
|
13052
13268
|
// focus into the frame yet when the window blurs.
|
|
13053
|
-
|
|
13269
|
+
var frame = classifyPaymentFrame(document.activeElement, window);
|
|
13270
|
+
kind = frame ? frame.kind : undefined;
|
|
13271
|
+
family = frame ? frame.family : undefined;
|
|
13054
13272
|
source = 'frame';
|
|
13055
13273
|
} else if (unconfirmedCommit && t - _this.lastCommitClick > SUBMIT_AFTER_COMMIT_CLICK_MS) {
|
|
13056
13274
|
kind = undefined;
|
|
@@ -13064,7 +13282,14 @@ var mParticle = (function () {
|
|
|
13064
13282
|
if (box && event.defaultPrevented) {
|
|
13065
13283
|
click.checked = box.type === 'checkbox' ? !click.checked : box.checked;
|
|
13066
13284
|
}
|
|
13067
|
-
_this.logClick(click, pathname);
|
|
13285
|
+
_this.logClick(click, pathname, asLink);
|
|
13286
|
+
}
|
|
13287
|
+
// Ahead of the intent, so a pre-selection it fires goes out
|
|
13288
|
+
// with this pick.
|
|
13289
|
+
if (choice && isPicked(choice.radio)) {
|
|
13290
|
+
_this.pickPayment(t, pathname, choice.names);
|
|
13291
|
+
} else if (family) {
|
|
13292
|
+
_this.pickPayment(t, pathname, undefined, family);
|
|
13068
13293
|
}
|
|
13069
13294
|
if (kind) {
|
|
13070
13295
|
_this.emit(kind, source, layer, t, pathname);
|
|
@@ -13075,8 +13300,8 @@ var mParticle = (function () {
|
|
|
13075
13300
|
});
|
|
13076
13301
|
};
|
|
13077
13302
|
// Every real click is one event, repeats included, up to a ceiling per page.
|
|
13078
|
-
ButtonTracker.prototype.logClick = function (click, pathname) {
|
|
13079
|
-
if (!this.eventsEnabled()) {
|
|
13303
|
+
ButtonTracker.prototype.logClick = function (click, pathname, asLink) {
|
|
13304
|
+
if (!this.eventsEnabled() || this.hasTargetingOptOut()) {
|
|
13080
13305
|
return;
|
|
13081
13306
|
}
|
|
13082
13307
|
if (pathname !== this.pagePath) {
|
|
@@ -13090,7 +13315,7 @@ var mParticle = (function () {
|
|
|
13090
13315
|
// Restarts an expired session, as public logEvent() and page views do.
|
|
13091
13316
|
this.mpInstance._SessionManager.resetSessionTimer();
|
|
13092
13317
|
var queued = this.queuedForUpload();
|
|
13093
|
-
this.mpInstance._Events.logEvent(buildButtonClickEvent(click, pathname));
|
|
13318
|
+
this.mpInstance._Events.logEvent(asLink ? buildLinkClickEvent(click, pathname) : buildButtonClickEvent(click, pathname));
|
|
13094
13319
|
// Only a click waiting for the batch interval is sent early: a held
|
|
13095
13320
|
// one goes out when released, and with batching off it already has.
|
|
13096
13321
|
// A checkbox or radio waits for the batch, since choosing an option
|
|
@@ -13152,11 +13377,29 @@ var mParticle = (function () {
|
|
|
13152
13377
|
pathname: pathname
|
|
13153
13378
|
}), pathname);
|
|
13154
13379
|
};
|
|
13380
|
+
ButtonTracker.prototype.pickPayment = function (t, pathname, names, family) {
|
|
13381
|
+
if (this.isKitSuppressed()) {
|
|
13382
|
+
return;
|
|
13383
|
+
}
|
|
13384
|
+
this.mpInstance._RoktManager.notifyPaymentPick(Object.freeze({
|
|
13385
|
+
t: t,
|
|
13386
|
+
pathname: pathname,
|
|
13387
|
+
names: names ? Object.freeze(names.slice()) : undefined,
|
|
13388
|
+
family: family
|
|
13389
|
+
}));
|
|
13390
|
+
};
|
|
13155
13391
|
// Events follow the SDK's opt-out like any other event.
|
|
13156
13392
|
ButtonTracker.prototype.eventsEnabled = function () {
|
|
13157
13393
|
var store = this.mpInstance._Store;
|
|
13158
13394
|
return !!store && store.isEnabled;
|
|
13159
13395
|
};
|
|
13396
|
+
// Read per click, since the launcher options can arrive after the tracker
|
|
13397
|
+
// starts. Only where this init configures a Rokt kit, so Global Privacy
|
|
13398
|
+
// Control alone doesn't stop click logging elsewhere.
|
|
13399
|
+
ButtonTracker.prototype.hasTargetingOptOut = function () {
|
|
13400
|
+
var roktManager = this.mpInstance._RoktManager;
|
|
13401
|
+
return this.hasRoktKit && !!roktManager && roktManager.hasTargetingOptOut();
|
|
13402
|
+
};
|
|
13160
13403
|
// The Rokt manager owns the kit's privacy gates: flag, opt-out, launcher
|
|
13161
13404
|
// options and Global Privacy Control.
|
|
13162
13405
|
ButtonTracker.prototype.isKitSuppressed = function () {
|
|
@@ -14101,7 +14344,8 @@ var mParticle = (function () {
|
|
|
14101
14344
|
var getFeatureFlag = mpInstance._Helpers.getFeatureFlag;
|
|
14102
14345
|
var _e = Constants.FeatureFlags,
|
|
14103
14346
|
AutoLogPageView = _e.AutoLogPageView,
|
|
14104
|
-
AutoButtonTracking = _e.AutoButtonTracking
|
|
14347
|
+
AutoButtonTracking = _e.AutoButtonTracking,
|
|
14348
|
+
AutoLinkTracking = _e.AutoLinkTracking;
|
|
14105
14349
|
// Destroy previous batch uploader to prevent leaked timers and event listeners
|
|
14106
14350
|
if ((_a = mpInstance._APIClient) === null || _a === void 0 ? void 0 : _a.uploader) {
|
|
14107
14351
|
mpInstance._APIClient.uploader.destroy();
|
|
@@ -14168,11 +14412,16 @@ var mParticle = (function () {
|
|
|
14168
14412
|
// Rokt kit only when that kit receives them. Set before
|
|
14169
14413
|
// processForwarders: the kit can read it during this init, from its own
|
|
14170
14414
|
// init or from a returning shopper's landing page view.
|
|
14415
|
+
var logButtons = !!getFeatureFlag(AutoButtonTracking);
|
|
14416
|
+
var logLinks = !!getFeatureFlag(AutoLinkTracking);
|
|
14417
|
+
// Links feed intent too, so with link tracking on the kit must also
|
|
14418
|
+
// receive Auto Link Click events.
|
|
14171
14419
|
var buttonClickBlocker = roktConfig_1 ? getButtonClickBlocker(roktConfig_1, kitBlocker) : undefined;
|
|
14172
|
-
|
|
14173
|
-
|
|
14420
|
+
var linkClickBlocker = roktConfig_1 && logLinks ? getButtonClickBlocker(roktConfig_1, kitBlocker, true) : undefined;
|
|
14421
|
+
if (logButtons && (buttonClickBlocker || linkClickBlocker)) {
|
|
14422
|
+
mpInstance.Logger.warning(buttonClickBlocker ? "Checkout intent is off: the ".concat(buttonClickBlocker, " keeps some or all Auto Button Click events from the Rokt kit.") : "Checkout intent is off: the ".concat(linkClickBlocker, " keeps some or all Auto Link Click events from the Rokt kit."));
|
|
14174
14423
|
}
|
|
14175
|
-
mpInstance._RoktManager.setAutoButtonClicksForwarded(!!roktConfig_1 && !buttonClickBlocker);
|
|
14424
|
+
mpInstance._RoktManager.setAutoButtonClicksForwarded(!!roktConfig_1 && !buttonClickBlocker && !linkClickBlocker);
|
|
14176
14425
|
mpInstance._Forwarders.processForwarders(config, mpInstance._APIClient.prepareForwardingStats);
|
|
14177
14426
|
mpInstance._Forwarders.processPixelConfigs(config);
|
|
14178
14427
|
// Checks if session is created, resumed, or needs to be ended
|
|
@@ -14207,12 +14456,14 @@ var mParticle = (function () {
|
|
|
14207
14456
|
// so it stops listening. Re-created if the flag is re-enabled later.
|
|
14208
14457
|
mpInstance._PageViewTracker.teardown();
|
|
14209
14458
|
}
|
|
14210
|
-
if (
|
|
14459
|
+
if (logButtons || logLinks) {
|
|
14211
14460
|
if (!mpInstance._ButtonTracker) {
|
|
14212
14461
|
mpInstance._ButtonTracker = new ButtonTracker(mpInstance);
|
|
14213
14462
|
}
|
|
14214
14463
|
mpInstance._ButtonTracker.init({
|
|
14215
|
-
hasRoktKit: !!roktConfig_1
|
|
14464
|
+
hasRoktKit: !!roktConfig_1,
|
|
14465
|
+
logButtons: logButtons,
|
|
14466
|
+
logLinks: logLinks
|
|
14216
14467
|
});
|
|
14217
14468
|
} else {
|
|
14218
14469
|
// Also retires a tracker left by an earlier bundle load. Like APV,
|
|
@@ -14318,10 +14569,12 @@ var mParticle = (function () {
|
|
|
14318
14569
|
// Initialize CookieConsentManager with privacy flags from launcherOptions
|
|
14319
14570
|
var _a = normalizeRoktLauncherOptions(config === null || config === void 0 ? void 0 : config.launcherOptions),
|
|
14320
14571
|
noFunctional = _a.noFunctional,
|
|
14321
|
-
noTargeting = _a.noTargeting
|
|
14572
|
+
noTargeting = _a.noTargeting,
|
|
14573
|
+
doNotShareOrSell = _a.doNotShareOrSell;
|
|
14322
14574
|
mpInstance._CookieConsentManager = new CookieConsentManager({
|
|
14323
14575
|
noFunctional: noFunctional,
|
|
14324
|
-
noTargeting: noTargeting
|
|
14576
|
+
noTargeting: noTargeting,
|
|
14577
|
+
doNotShareOrSell: doNotShareOrSell
|
|
14325
14578
|
});
|
|
14326
14579
|
// Check to see if localStorage is available before main configuration runs
|
|
14327
14580
|
// since we will need this for the current implementation of user persistence
|