@mparticle/web-sdk 3.24.0 → 3.26.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 +372 -93
- 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 +7 -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 +11 -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 +129 -20
- package/src/buttonTracking/checkoutIntent.ts +85 -27
- 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 +59 -10
- 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.26.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) {
|
|
@@ -10874,8 +10881,9 @@ var mParticle = (function () {
|
|
|
10874
10881
|
}
|
|
10875
10882
|
|
|
10876
10883
|
var PASSBACK_CONVERSION_TRACKING_ID = 'passbackconversiontrackingid';
|
|
10877
|
-
// One signal per kind (commit, wallet, checkout_step, frame and cart),
|
|
10878
|
-
|
|
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;
|
|
10879
10887
|
var CHECKOUT_INTENT_MAX_AGE_MS = 30000;
|
|
10880
10888
|
var ON_SHOPPABLE_ADS_READY_METHOD = 'onShoppableAdsReady';
|
|
10881
10889
|
// The purpose of this class is to create a link between the Core mParticle SDK and the
|
|
@@ -11035,21 +11043,27 @@ var mParticle = (function () {
|
|
|
11035
11043
|
RoktManager.prototype.setAutoButtonClicksForwarded = function (forwarded) {
|
|
11036
11044
|
this.autoButtonClicksForwarded = forwarded;
|
|
11037
11045
|
};
|
|
11046
|
+
// noTargeting (which noDeviceId implies), doNotShareOrSell or Global Privacy
|
|
11047
|
+
// Control. Unlike noFunctional, these also stop auto button and link clicks
|
|
11048
|
+
// from being logged.
|
|
11049
|
+
RoktManager.prototype.hasTargetingOptOut = function () {
|
|
11050
|
+
var options = this.launcherOptions || {};
|
|
11051
|
+
if (options.noTargeting || options.doNotShareOrSell) {
|
|
11052
|
+
return true;
|
|
11053
|
+
}
|
|
11054
|
+
var nav = typeof navigator === 'undefined' ? undefined : navigator;
|
|
11055
|
+
return !!nav && nav.globalPrivacyControl === true;
|
|
11056
|
+
};
|
|
11038
11057
|
// Checkout intent is off unless the flag is on, and under opt-out, any Rokt
|
|
11039
11058
|
// privacy launcher option, Global Privacy Control, or a Rokt connection that
|
|
11040
11059
|
// does not receive auto button clicks.
|
|
11041
11060
|
RoktManager.prototype.isCheckoutIntentSuppressed = function () {
|
|
11042
|
-
var _a, _b;
|
|
11061
|
+
var _a, _b, _c;
|
|
11043
11062
|
var flags = (_b = (_a = this.store) === null || _a === void 0 ? void 0 : _a.SDKConfig) === null || _b === void 0 ? void 0 : _b.flags;
|
|
11044
11063
|
if (!flags || flags[Constants.FeatureFlags.AutoButtonTracking] !== true || !this.store.isEnabled || !this.autoButtonClicksForwarded) {
|
|
11045
11064
|
return true;
|
|
11046
11065
|
}
|
|
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;
|
|
11066
|
+
return !!((_c = this.launcherOptions) === null || _c === void 0 ? void 0 : _c.noFunctional) || this.hasTargetingOptOut();
|
|
11053
11067
|
};
|
|
11054
11068
|
// True when the kit can wait for the shopper's confirm click: signals are not
|
|
11055
11069
|
// suppressed and the browser exposes the composed path the detector reads.
|
|
@@ -11072,8 +11086,10 @@ var mParticle = (function () {
|
|
|
11072
11086
|
}
|
|
11073
11087
|
var kit = this.kit;
|
|
11074
11088
|
if (!kit) {
|
|
11089
|
+
// One per kind, with an add-to-cart click kept apart from a
|
|
11090
|
+
// click that opens the cart.
|
|
11075
11091
|
this.pendingCheckoutIntents = this.pendingCheckoutIntents.filter(function (pending) {
|
|
11076
|
-
return pending.signal.kind !== signal.kind;
|
|
11092
|
+
return pending.signal.kind !== signal.kind || !!pending.signal.adds !== !!signal.adds;
|
|
11077
11093
|
}).concat({
|
|
11078
11094
|
signal: signal,
|
|
11079
11095
|
pathname: pathname
|
|
@@ -11091,6 +11107,23 @@ var mParticle = (function () {
|
|
|
11091
11107
|
RoktManager.prototype.discardCheckoutIntents = function () {
|
|
11092
11108
|
this.pendingCheckoutIntents = [];
|
|
11093
11109
|
};
|
|
11110
|
+
// Under the same gates as checkout intent. A pick made before a kit
|
|
11111
|
+
// attaches is not kept: the shopper is still choosing, and the next pick
|
|
11112
|
+
// replaces it.
|
|
11113
|
+
RoktManager.prototype.notifyPaymentPick = function (signal) {
|
|
11114
|
+
var _a;
|
|
11115
|
+
if (this.isCheckoutIntentSuppressed()) {
|
|
11116
|
+
return;
|
|
11117
|
+
}
|
|
11118
|
+
var kit = this.kit;
|
|
11119
|
+
try {
|
|
11120
|
+
if (kit && isFunction(kit.onPaymentPick)) {
|
|
11121
|
+
kit.onPaymentPick(signal);
|
|
11122
|
+
}
|
|
11123
|
+
} catch (e) {
|
|
11124
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.error("RoktManager: Error in onPaymentPick: ".concat(getErrorMessage(e)));
|
|
11125
|
+
}
|
|
11126
|
+
};
|
|
11094
11127
|
// Replays recent buffered signals raised on the current page, oldest first.
|
|
11095
11128
|
RoktManager.prototype.flushCheckoutIntents = function () {
|
|
11096
11129
|
var _this = this;
|
|
@@ -11646,12 +11679,12 @@ var mParticle = (function () {
|
|
|
11646
11679
|
}();
|
|
11647
11680
|
|
|
11648
11681
|
/**
|
|
11649
|
-
* CookieConsentManager handles storage and access of consent flags (noFunctional, noTargeting
|
|
11650
|
-
* that are passed via launcherOptions during SDK initialization.
|
|
11682
|
+
* CookieConsentManager handles storage and access of consent flags (noFunctional, noTargeting,
|
|
11683
|
+
* doNotShareOrSell) that are passed via launcherOptions during SDK initialization.
|
|
11651
11684
|
*
|
|
11652
11685
|
* These flags allow Rokt integration to respect user privacy choices.
|
|
11653
11686
|
*
|
|
11654
|
-
* Default behavior:
|
|
11687
|
+
* Default behavior: All flags default to false, meaning all features are allowed
|
|
11655
11688
|
* unless explicitly opted out by the user.
|
|
11656
11689
|
*/
|
|
11657
11690
|
var CookieConsentManager = /** @class */function () {
|
|
@@ -11659,7 +11692,8 @@ var mParticle = (function () {
|
|
|
11659
11692
|
this.flags = flags;
|
|
11660
11693
|
this.flags = {
|
|
11661
11694
|
noFunctional: flags.noFunctional === true,
|
|
11662
|
-
noTargeting: flags.noTargeting === true
|
|
11695
|
+
noTargeting: flags.noTargeting === true,
|
|
11696
|
+
doNotShareOrSell: flags.doNotShareOrSell === true
|
|
11663
11697
|
};
|
|
11664
11698
|
}
|
|
11665
11699
|
/**
|
|
@@ -11676,6 +11710,13 @@ var mParticle = (function () {
|
|
|
11676
11710
|
CookieConsentManager.prototype.getNoFunctional = function () {
|
|
11677
11711
|
return this.flags.noFunctional;
|
|
11678
11712
|
};
|
|
11713
|
+
/**
|
|
11714
|
+
* Returns true if the user has opted out of the sale or sharing of their data.
|
|
11715
|
+
* Sharing is allowed when doNotShareOrSell is false (default).
|
|
11716
|
+
*/
|
|
11717
|
+
CookieConsentManager.prototype.getDoNotShareOrSell = function () {
|
|
11718
|
+
return this.flags.doNotShareOrSell;
|
|
11719
|
+
};
|
|
11679
11720
|
CookieConsentManager.prototype.syncNoTargetingAttribute = function (user) {
|
|
11680
11721
|
if (!user) return;
|
|
11681
11722
|
if (this.flags.noTargeting) {
|
|
@@ -11733,19 +11774,20 @@ var mParticle = (function () {
|
|
|
11733
11774
|
var AUTO_BUTTON_ATTRIBUTE = 'is_auto_button_click';
|
|
11734
11775
|
// Specific enough not to merge with a customer's own 'Button Click' event.
|
|
11735
11776
|
var BUTTON_CLICK_EVENT_NAME = 'Auto Button Click';
|
|
11736
|
-
//
|
|
11737
|
-
|
|
11738
|
-
|
|
11739
|
-
|
|
11740
|
-
|
|
11741
|
-
|
|
11777
|
+
// Marks an automatically logged click on a link that leaves the page.
|
|
11778
|
+
var AUTO_LINK_ATTRIBUTE = 'is_auto_link_click';
|
|
11779
|
+
var LINK_CLICK_EVENT_NAME = 'Auto Link Click';
|
|
11780
|
+
// The attributes both click events carry, with the page fields that auto page
|
|
11781
|
+
// views carry. No intent: classifying clicks is left to whoever reads the data.
|
|
11782
|
+
var clickAttributes = function clickAttributes(click, pathname) {
|
|
11783
|
+
var data = {
|
|
11742
11784
|
label_source: click.labelSource,
|
|
11743
11785
|
element: click.element,
|
|
11744
11786
|
type: click.type,
|
|
11745
11787
|
path: pathname,
|
|
11746
11788
|
hostname: window.location.hostname
|
|
11747
|
-
}
|
|
11748
|
-
// Optional fields are left out when the
|
|
11789
|
+
};
|
|
11790
|
+
// Optional fields are left out when the control has no safe value for them.
|
|
11749
11791
|
var optional = {
|
|
11750
11792
|
label: click.label,
|
|
11751
11793
|
aria_label: click.ariaLabel,
|
|
@@ -11759,8 +11801,8 @@ var mParticle = (function () {
|
|
|
11759
11801
|
link_domain: click.linkDomain,
|
|
11760
11802
|
file_extension: click.fileExtension
|
|
11761
11803
|
};
|
|
11762
|
-
for (var _i = 0,
|
|
11763
|
-
var key =
|
|
11804
|
+
for (var _i = 0, _a = Object.keys(optional); _i < _a.length; _i++) {
|
|
11805
|
+
var key = _a[_i];
|
|
11764
11806
|
if (optional[key]) {
|
|
11765
11807
|
data[key] = optional[key];
|
|
11766
11808
|
}
|
|
@@ -11768,6 +11810,12 @@ var mParticle = (function () {
|
|
|
11768
11810
|
if (click.checked !== undefined) {
|
|
11769
11811
|
data.checked = click.checked;
|
|
11770
11812
|
}
|
|
11813
|
+
return data;
|
|
11814
|
+
};
|
|
11815
|
+
// One custom event per button click, logged like logLink() with the auto marker.
|
|
11816
|
+
var buildButtonClickEvent = function buildButtonClickEvent(click, pathname) {
|
|
11817
|
+
var data = clickAttributes(click, pathname);
|
|
11818
|
+
data[AUTO_BUTTON_ATTRIBUTE] = true;
|
|
11771
11819
|
return {
|
|
11772
11820
|
messageType: MessageType$1.PageEvent,
|
|
11773
11821
|
name: BUTTON_CLICK_EVENT_NAME,
|
|
@@ -11775,28 +11823,52 @@ var mParticle = (function () {
|
|
|
11775
11823
|
eventType: EventType.Other
|
|
11776
11824
|
};
|
|
11777
11825
|
};
|
|
11826
|
+
// One custom event per click on a link that leaves the page. Typed Other, not
|
|
11827
|
+
// Navigation, so no kit reads it as a page change. A plain link to another page
|
|
11828
|
+
// of the site goes without its text, which can name the shopper ("Hi, Jane");
|
|
11829
|
+
// a button or wallet acting as a link keeps its name.
|
|
11830
|
+
var buildLinkClickEvent = function buildLinkClickEvent(click, pathname) {
|
|
11831
|
+
var data = clickAttributes(click.linkType === 'internal' && click.element === 'link' ? __assign(__assign({}, click), {
|
|
11832
|
+
label: undefined,
|
|
11833
|
+
labelSource: 'none',
|
|
11834
|
+
ariaLabel: undefined
|
|
11835
|
+
}) : click, pathname);
|
|
11836
|
+
data[AUTO_LINK_ATTRIBUTE] = true;
|
|
11837
|
+
return {
|
|
11838
|
+
messageType: MessageType$1.PageEvent,
|
|
11839
|
+
name: LINK_CLICK_EVENT_NAME,
|
|
11840
|
+
data: data,
|
|
11841
|
+
eventType: EventType.Other
|
|
11842
|
+
};
|
|
11843
|
+
};
|
|
11778
11844
|
// Every attribute buildButtonClickEvent can set apart from the marker and the
|
|
11779
11845
|
// hostname, which is the same on every click on this page. A spec checks the
|
|
11780
11846
|
// two stay in step.
|
|
11781
11847
|
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
|
-
|
|
11848
|
+
// Which check keeps some or all auto button clicks, or auto link clicks with
|
|
11849
|
+
// `link`, from a kit, or undefined when the kit receives every one. A forwarding
|
|
11850
|
+
// rule on an attribute whose value differs between clicks lets some through and
|
|
11851
|
+
// not others. Each other check goes through isEventForwarded on its own, so
|
|
11852
|
+
// together they decide as it does for each click.
|
|
11853
|
+
var getButtonClickBlocker = function getButtonClickBlocker(forwarder, kitBlocker, link) {
|
|
11854
|
+
if (link === void 0) {
|
|
11855
|
+
link = false;
|
|
11856
|
+
}
|
|
11789
11857
|
var rule = forwarder.filteringEventAttributeValue;
|
|
11790
11858
|
if (rule && rule.eventAttributeValue && CLICK_ATTRIBUTES.some(function (name) {
|
|
11791
11859
|
return KitFilterHelper.hashAttributeConditionalForwarding(name) === rule.eventAttributeName;
|
|
11792
11860
|
})) {
|
|
11793
11861
|
return 'forwarding rule';
|
|
11794
11862
|
}
|
|
11863
|
+
var attributes = {
|
|
11864
|
+
hostname: window.location.hostname
|
|
11865
|
+
};
|
|
11866
|
+
attributes[link ? AUTO_LINK_ATTRIBUTE : AUTO_BUTTON_ATTRIBUTE] = true;
|
|
11795
11867
|
var click = {
|
|
11796
|
-
EventName: BUTTON_CLICK_EVENT_NAME,
|
|
11868
|
+
EventName: link ? LINK_CLICK_EVENT_NAME : BUTTON_CLICK_EVENT_NAME,
|
|
11797
11869
|
EventCategory: EventType.Other,
|
|
11798
11870
|
EventDataType: MessageType$1.PageEvent,
|
|
11799
|
-
EventAttributes:
|
|
11871
|
+
EventAttributes: attributes
|
|
11800
11872
|
};
|
|
11801
11873
|
var checks = [['data plan', {}], ['forwarding rule', {
|
|
11802
11874
|
filteringEventAttributeValue: rule
|
|
@@ -12020,9 +12092,13 @@ var mParticle = (function () {
|
|
|
12020
12092
|
return control;
|
|
12021
12093
|
}
|
|
12022
12094
|
// 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
|
-
|
|
12095
|
+
// fields, editable regions, and anything under data-mp-no-track. `own` is a
|
|
12096
|
+
// box the element labels, which holds no typing of its own.
|
|
12097
|
+
function isUnsafeTextSource(element, own) {
|
|
12098
|
+
var inside = 'input, select, textarea, [data-mp-no-track], ' + EDITABLE;
|
|
12099
|
+
return element.matches('input, select, textarea, option, optgroup, datalist, ' + EDITABLE) || (own ? Array.from(element.querySelectorAll(inside)).some(function (found) {
|
|
12100
|
+
return found !== own;
|
|
12101
|
+
}) : !!element.querySelector(inside)) || hasComposedAncestor(element, 'select, datalist, textarea, [data-mp-no-track], ' + EDITABLE);
|
|
12026
12102
|
}
|
|
12027
12103
|
|
|
12028
12104
|
// Masks a button label before it is logged. Button text can carry personal data,
|
|
@@ -12363,8 +12439,8 @@ var mParticle = (function () {
|
|
|
12363
12439
|
return tag === 'button' || tag === 'input' ? control.type : 'button';
|
|
12364
12440
|
}
|
|
12365
12441
|
// 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
|
-
//
|
|
12442
|
+
// a link that leaves the site and the extension of a file it downloads travel.
|
|
12443
|
+
// mailto:, tel: and other schemes give undefined.
|
|
12368
12444
|
function describeLink(link) {
|
|
12369
12445
|
var href = (link.getAttribute('href') || '').trim();
|
|
12370
12446
|
if (!href || href.charAt(0) === '#') {
|
|
@@ -12401,7 +12477,14 @@ var mParticle = (function () {
|
|
|
12401
12477
|
}
|
|
12402
12478
|
return link.pathname === window.location.pathname && link.search === window.location.search ? {
|
|
12403
12479
|
type: 'same_page'
|
|
12404
|
-
} :
|
|
12480
|
+
} : {
|
|
12481
|
+
type: 'internal'
|
|
12482
|
+
};
|
|
12483
|
+
}
|
|
12484
|
+
// Whether a described click is on a link that leaves the page, logged as a link
|
|
12485
|
+
// click rather than a button click.
|
|
12486
|
+
function isLinkClick(click) {
|
|
12487
|
+
return !!click.linkType && click.linkType !== 'same_page';
|
|
12405
12488
|
}
|
|
12406
12489
|
// Checkboxes and radios, and the roles that act as them. A role can list
|
|
12407
12490
|
// fallbacks, so any of its tokens counts.
|
|
@@ -12411,6 +12494,9 @@ var mParticle = (function () {
|
|
|
12411
12494
|
var box = element instanceof HTMLLabelElement ? element.control : element;
|
|
12412
12495
|
return box && box.matches(CHOICE) ? box : null;
|
|
12413
12496
|
}
|
|
12497
|
+
function isRadio(choice) {
|
|
12498
|
+
return choice instanceof HTMLInputElement ? choice.type === 'radio' : !!choice && choice.matches(RADIO_ROLE);
|
|
12499
|
+
}
|
|
12414
12500
|
// The box a click on this control picks. One the click passed through below
|
|
12415
12501
|
// the control comes first: querySelector can't reach a slotted box, a box in a
|
|
12416
12502
|
// shadow root or the box of a label inside the control, and a row can hold
|
|
@@ -12429,8 +12515,9 @@ var mParticle = (function () {
|
|
|
12429
12515
|
}
|
|
12430
12516
|
return boxOf(control) || control.querySelector(CHOICE);
|
|
12431
12517
|
}
|
|
12432
|
-
// Describes a clicked control for auto button tracking. A link
|
|
12433
|
-
//
|
|
12518
|
+
// Describes a clicked control for auto button and link tracking. A link carries its
|
|
12519
|
+
// link type, and one to another scheme is skipped. A role="button" anchor carries one
|
|
12520
|
+
// only when it leaves the page; otherwise it stays a plain button.
|
|
12434
12521
|
function describeButtonClick(control, path) {
|
|
12435
12522
|
if (path === void 0) {
|
|
12436
12523
|
path = [];
|
|
@@ -12441,6 +12528,11 @@ var mParticle = (function () {
|
|
|
12441
12528
|
if (!link) {
|
|
12442
12529
|
return undefined;
|
|
12443
12530
|
}
|
|
12531
|
+
} else if (control.matches('a[href]')) {
|
|
12532
|
+
link = describeLink(control);
|
|
12533
|
+
if (link && link.type === 'same_page') {
|
|
12534
|
+
link = undefined;
|
|
12535
|
+
}
|
|
12444
12536
|
}
|
|
12445
12537
|
var element = elementKind(control);
|
|
12446
12538
|
var box = control instanceof HTMLInputElement && (control.type === 'checkbox' || control.type === 'radio') ? control : undefined;
|
|
@@ -12454,7 +12546,7 @@ var mParticle = (function () {
|
|
|
12454
12546
|
// radio's id, test id and the panel it opens name the option picked, so
|
|
12455
12547
|
// only the name of its input, the question, goes with it. A wrapper's own
|
|
12456
12548
|
// name, or a role radio's, can name the option instead.
|
|
12457
|
-
var radio = choice
|
|
12549
|
+
var radio = isRadio(choice);
|
|
12458
12550
|
var named = !radio ? control : choice instanceof HTMLInputElement ? choice : null;
|
|
12459
12551
|
var name = choice ? undefined : accessibleName(control);
|
|
12460
12552
|
var label = name ? maskLabel(name.raw) : undefined;
|
|
@@ -12480,6 +12572,54 @@ var mParticle = (function () {
|
|
|
12480
12572
|
checked: box ? box.checked : undefined
|
|
12481
12573
|
};
|
|
12482
12574
|
}
|
|
12575
|
+
// A question about payment, read from the names its author gave it, so
|
|
12576
|
+
// "checkout[payment_gateway]", "paymentMethod" and "tender_type" all count and
|
|
12577
|
+
// "payee" does not. A radio's input name is its question; its group or
|
|
12578
|
+
// fieldset speaks only for a radio with no name, as a role radio usually is.
|
|
12579
|
+
var PAYMENT_QUESTION = /(?:^| )(?:pay|payment\w*|tenders?|gateways?)(?: |$)/;
|
|
12580
|
+
var QUESTION_GROUP = '[role="radiogroup"], fieldset';
|
|
12581
|
+
function isPaymentQuestion(radio) {
|
|
12582
|
+
var name = radio.getAttribute('name');
|
|
12583
|
+
var group = name ? null : radio.closest(QUESTION_GROUP);
|
|
12584
|
+
var question = group ? [group.getAttribute('id'), group.getAttribute('name'), group.getAttribute('aria-label')] : [name];
|
|
12585
|
+
return question.some(function (words) {
|
|
12586
|
+
return PAYMENT_QUESTION.test(nameWords(words));
|
|
12587
|
+
});
|
|
12588
|
+
}
|
|
12589
|
+
// What names a payment option: the radio's accessible name, the text and
|
|
12590
|
+
// image of each label, and its hand-written ids, text masked like a label.
|
|
12591
|
+
function optionNames(radio) {
|
|
12592
|
+
var names = [maskLabel(accessibleName(radio).raw)];
|
|
12593
|
+
var labels = radio instanceof HTMLInputElement && radio.labels ? Array.from(radio.labels).slice(0, 2) : [];
|
|
12594
|
+
labels.forEach(function (label) {
|
|
12595
|
+
if (isShown(label) && !isUnsafeTextSource(label, radio)) {
|
|
12596
|
+
names.push(maskLabel(renderedText(label)));
|
|
12597
|
+
names.push(maskLabel(shownImageAlt(label)));
|
|
12598
|
+
}
|
|
12599
|
+
});
|
|
12600
|
+
names.push(stableIdentifier(radio.getAttribute('id')), firstIdentifier(radio, TEST_ID_ATTRIBUTES));
|
|
12601
|
+
return names.filter(function (name, index) {
|
|
12602
|
+
return !!name && names.indexOf(name) === index;
|
|
12603
|
+
});
|
|
12604
|
+
}
|
|
12605
|
+
function describePaymentChoice(control, path) {
|
|
12606
|
+
if (path === void 0) {
|
|
12607
|
+
path = [];
|
|
12608
|
+
}
|
|
12609
|
+
var choice = choiceOf(control, path);
|
|
12610
|
+
if (!isRadio(choice) || hasComposedAncestor(choice, '[data-mp-no-track]') || !isPaymentQuestion(choice)) {
|
|
12611
|
+
return undefined;
|
|
12612
|
+
}
|
|
12613
|
+
var names = optionNames(choice);
|
|
12614
|
+
return names.length ? {
|
|
12615
|
+
radio: choice,
|
|
12616
|
+
names: names
|
|
12617
|
+
} : undefined;
|
|
12618
|
+
}
|
|
12619
|
+
// Read once the page has handled the click, which may have cancelled it.
|
|
12620
|
+
function isPicked(radio) {
|
|
12621
|
+
return radio instanceof HTMLInputElement ? radio.checked : radio.getAttribute('aria-checked') === 'true';
|
|
12622
|
+
}
|
|
12483
12623
|
|
|
12484
12624
|
var checkoutPath = /(?:^|\/)(?:checkouts?|payment|order|kasse|paiement|commander?|pago)(?:\/|$)/i;
|
|
12485
12625
|
// English look-alikes are whole words; the other languages stay substring
|
|
@@ -12495,9 +12635,11 @@ var mParticle = (function () {
|
|
|
12495
12635
|
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
12636
|
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
12637
|
var CART_NOUN = '(?:(?:my|your|the) )?(?:shopping )?(?:cart|bag|basket)';
|
|
12498
|
-
// "Add to bag"
|
|
12499
|
-
|
|
12500
|
-
|
|
12638
|
+
// "Add to bag" and "Add 2 to cart": a click that puts something in the cart.
|
|
12639
|
+
var addToCartLabels = new RegExp('^add(?: [^ ]+){0,5} to ' + CART_NOUN + '$');
|
|
12640
|
+
// "View cart", "Shopping bag", "Bag", and a count badge such as "1 item in bag",
|
|
12641
|
+
// which reads "item in bag" once digits are stripped: a click that opens the cart.
|
|
12642
|
+
var openCartLabels = new RegExp('^(?:(?:(?:view|open|go to) )?' + CART_NOUN + '(?: items?)?' + '|items? in ' + CART_NOUN + ')$');
|
|
12501
12643
|
var WALLET_NAMES = 'apple pay|google pay|paypal|venmo|amazon pay|shop pay|klarna|afterpay|clearpay|cash app(?: pay)?|affirm|sezzle|samsung pay';
|
|
12502
12644
|
var WALLET_VERBS = 'pay|buy|purchase|order|book|donate|subscribe|check ?out|checkout|express checkout|continue|proceed|' + 'complete purchase|place (?:my |your )?order';
|
|
12503
12645
|
// "Pay with Klarna", "Buy with GPay", "Continue to PayPal".
|
|
@@ -12505,14 +12647,27 @@ var mParticle = (function () {
|
|
|
12505
12647
|
// A wallet's own name on a button: "PayPal", "Klarna checkout", "Apple Pay logo".
|
|
12506
12648
|
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
12649
|
// Exact HTTPS hosts of hosted wallet button frames.
|
|
12508
|
-
var
|
|
12650
|
+
var walletFrameFamilies = {
|
|
12651
|
+
'pay.google.com': 'google_pay',
|
|
12652
|
+
'applepay.cdn-apple.com': 'apple_pay',
|
|
12653
|
+
'payments.amazon.com': 'amazon_pay',
|
|
12654
|
+
'pay.shopify.com': 'shop_pay'
|
|
12655
|
+
};
|
|
12509
12656
|
// PayPal serves its buttons and its card fields and pay-later messages from
|
|
12510
12657
|
// the same hosts; only the button frames are wallet taps.
|
|
12511
12658
|
var paypalFrameHosts = new Set(['www.paypal.com', 'www.sandbox.paypal.com']);
|
|
12512
12659
|
var PAYPAL_BUTTON_FRAME = /^\/smart\/(?:buttons|menu)(?:\/|$)/;
|
|
12660
|
+
var PAYPAL_CARD_FRAME = /^\/smart\/card-fields?(?:\/|$)/;
|
|
12661
|
+
// PayPal's JS SDK, used directly or wrapped by a processor, leaves its frames
|
|
12662
|
+
// without a src and names them __zoid__paypal_<component>__ instead.
|
|
12663
|
+
var PAYPAL_SDK_FRAME = /^__zoid__paypal_/;
|
|
12664
|
+
var PAYPAL_SDK_BUTTON_FRAME = /^__zoid__paypal_(?:buttons|menu)__/;
|
|
12513
12665
|
// Stripe's quick-pay button frames; its other frames are card and form fields.
|
|
12514
12666
|
var STRIPE_WALLET_FRAME = /\/elements-inner-(?:payment-request|express-checkout)-/;
|
|
12667
|
+
var STRIPE_CARD_FRAME = /\/elements-inner-card\b/;
|
|
12515
12668
|
// Hosted card-entry and fingerprint frames: focus there is typing card details.
|
|
12669
|
+
// Some of these hosts also serve gift card and bank account fields, so none
|
|
12670
|
+
// names a family.
|
|
12516
12671
|
var CARD_FRAME_DOMAINS = ['adyen.com', 'braintreegateway.com', 'cybersource.com', 'squarecdn.com', 'checkout.com'];
|
|
12517
12672
|
// Keep these classes ASCII-only in source bytes to avoid mojibake parse failures
|
|
12518
12673
|
// when a host page forces non-UTF-8 decoding before JavaScript parse.
|
|
@@ -12574,12 +12729,20 @@ var mParticle = (function () {
|
|
|
12574
12729
|
});
|
|
12575
12730
|
}
|
|
12576
12731
|
// 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.
|
|
12578
|
-
|
|
12732
|
+
// does. Only the cart rule reads the title. Opening the cart counts only for a
|
|
12733
|
+
// control that opens it on the page, such as a flyout: one that leads to the cart
|
|
12734
|
+
// page unloads before a call made on the click can return.
|
|
12735
|
+
function cartControlAction(control, cores) {
|
|
12579
12736
|
var title = cores.length ? undefined : normalize(control.getAttribute('title'));
|
|
12580
|
-
|
|
12581
|
-
|
|
12582
|
-
|
|
12737
|
+
var texts = title ? [coreLabel(title)] : cores;
|
|
12738
|
+
if (texts.some(function (text) {
|
|
12739
|
+
return addToCartLabels.test(text);
|
|
12740
|
+
})) {
|
|
12741
|
+
return 'add';
|
|
12742
|
+
}
|
|
12743
|
+
return (control.hasAttribute('aria-expanded') || control.hasAttribute('aria-haspopup')) && texts.some(function (text) {
|
|
12744
|
+
return openCartLabels.test(text);
|
|
12745
|
+
}) ? 'open' : undefined;
|
|
12583
12746
|
}
|
|
12584
12747
|
// "Buy now" and "Purchase" count only on a checkout route, and never on a plain
|
|
12585
12748
|
// link, which is navigation.
|
|
@@ -12593,8 +12756,8 @@ var mParticle = (function () {
|
|
|
12593
12756
|
// pickers, toggles and pay-later messages never count; a vendor's own wallet
|
|
12594
12757
|
// button counts before any label rule; a confirm label on any source counts
|
|
12595
12758
|
// before the look-alike exclusions veto; then a wallet-named control, wallet
|
|
12596
|
-
// phrases and steps.
|
|
12597
|
-
// those do.
|
|
12759
|
+
// phrases and steps. An add-to-cart label, links included, or a control that
|
|
12760
|
+
// opens the cart on the page counts only where none of those do.
|
|
12598
12761
|
function classifyIntent(control, pathname) {
|
|
12599
12762
|
var vendor = vendorButtonKind(control);
|
|
12600
12763
|
if (vendor === 'none') {
|
|
@@ -12608,10 +12771,20 @@ var mParticle = (function () {
|
|
|
12608
12771
|
}
|
|
12609
12772
|
var texts = labels(control);
|
|
12610
12773
|
var cores = texts.map(coreLabel);
|
|
12611
|
-
var
|
|
12612
|
-
|
|
12613
|
-
|
|
12614
|
-
|
|
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
|
+
}
|
|
12615
12788
|
if (isQuietIntentControl(control, false, !!cart)) {
|
|
12616
12789
|
return undefined;
|
|
12617
12790
|
}
|
|
@@ -12668,30 +12841,66 @@ var mParticle = (function () {
|
|
|
12668
12841
|
return host === domain || host.length > domain.length && host.slice(host.length - domain.length - 1) === '.' + domain;
|
|
12669
12842
|
}
|
|
12670
12843
|
// 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
|
-
|
|
12844
|
+
// focus into hosted card fields or messages is only a frame. A family comes
|
|
12845
|
+
// only from a frame that can draw no other method: PayPal's button frame also
|
|
12846
|
+
// draws Pay Later, Venmo and its card form, Stripe's quick-pay frame draws
|
|
12847
|
+
// Apple Pay or Google Pay by browser, and its payment form holds several.
|
|
12848
|
+
function classifyPaymentFrame(target, win) {
|
|
12673
12849
|
if (win.document.visibilityState !== 'visible' || !(target instanceof HTMLIFrameElement)) {
|
|
12674
12850
|
return undefined;
|
|
12675
12851
|
}
|
|
12676
12852
|
if (isRoktElement(target) || hasComposedAncestor(target, '[data-mp-no-track]')) {
|
|
12677
12853
|
return undefined;
|
|
12678
12854
|
}
|
|
12855
|
+
// A frame that has its own src is judged by that address, never by its name.
|
|
12856
|
+
if ((!target.src || target.src === 'about:blank') && PAYPAL_SDK_FRAME.test(target.name)) {
|
|
12857
|
+
return PAYPAL_SDK_BUTTON_FRAME.test(target.name) ? {
|
|
12858
|
+
kind: 'wallet'
|
|
12859
|
+
} : {
|
|
12860
|
+
kind: 'frame'
|
|
12861
|
+
};
|
|
12862
|
+
}
|
|
12679
12863
|
try {
|
|
12680
12864
|
var url = new URL(target.src);
|
|
12681
12865
|
var host_1 = url.protocol === 'https:' ? url.hostname : '';
|
|
12682
12866
|
if (paypalFrameHosts.has(host_1)) {
|
|
12683
|
-
|
|
12867
|
+
if (PAYPAL_BUTTON_FRAME.test(url.pathname)) {
|
|
12868
|
+
return {
|
|
12869
|
+
kind: 'wallet'
|
|
12870
|
+
};
|
|
12871
|
+
}
|
|
12872
|
+
return PAYPAL_CARD_FRAME.test(url.pathname) ? {
|
|
12873
|
+
kind: 'frame',
|
|
12874
|
+
family: 'card'
|
|
12875
|
+
} : {
|
|
12876
|
+
kind: 'frame'
|
|
12877
|
+
};
|
|
12684
12878
|
}
|
|
12685
|
-
if (
|
|
12686
|
-
return
|
|
12879
|
+
if (Object.prototype.hasOwnProperty.call(walletFrameFamilies, host_1)) {
|
|
12880
|
+
return {
|
|
12881
|
+
kind: 'wallet',
|
|
12882
|
+
family: walletFrameFamilies[host_1]
|
|
12883
|
+
};
|
|
12687
12884
|
}
|
|
12688
12885
|
if (host_1 === 'js.stripe.com') {
|
|
12689
|
-
|
|
12886
|
+
if (STRIPE_WALLET_FRAME.test(url.pathname)) {
|
|
12887
|
+
return {
|
|
12888
|
+
kind: 'wallet'
|
|
12889
|
+
};
|
|
12890
|
+
}
|
|
12891
|
+
return STRIPE_CARD_FRAME.test(url.pathname) ? {
|
|
12892
|
+
kind: 'frame',
|
|
12893
|
+
family: 'card'
|
|
12894
|
+
} : {
|
|
12895
|
+
kind: 'frame'
|
|
12896
|
+
};
|
|
12690
12897
|
}
|
|
12691
12898
|
if (CARD_FRAME_DOMAINS.some(function (domain) {
|
|
12692
12899
|
return isOnDomain(host_1, domain);
|
|
12693
12900
|
})) {
|
|
12694
|
-
return
|
|
12901
|
+
return {
|
|
12902
|
+
kind: 'frame'
|
|
12903
|
+
};
|
|
12695
12904
|
}
|
|
12696
12905
|
} catch (e) {
|
|
12697
12906
|
// An unparseable frame src is not a wallet frame.
|
|
@@ -12808,13 +13017,17 @@ var mParticle = (function () {
|
|
|
12808
13017
|
var PASSIVE = {
|
|
12809
13018
|
passive: true
|
|
12810
13019
|
};
|
|
12811
|
-
// Logs
|
|
12812
|
-
// Rokt kit as a frozen {kind, t, source, pathname}
|
|
13020
|
+
// Logs button clicks and clicks on links that leave the page as mParticle events, and hands checkout
|
|
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.
|
|
12813
13024
|
var ButtonTracker = /** @class */function () {
|
|
12814
13025
|
function ButtonTracker(mpInstance) {
|
|
12815
13026
|
var _this = this;
|
|
12816
13027
|
this.active = false;
|
|
12817
13028
|
this.hasRoktKit = false;
|
|
13029
|
+
this.logButtons = false;
|
|
13030
|
+
this.logLinks = false;
|
|
12818
13031
|
// Bumped on reset so classification queued before it is dropped.
|
|
12819
13032
|
this.generation = 0;
|
|
12820
13033
|
this.lastCommitClick = -Infinity;
|
|
@@ -12888,7 +13101,9 @@ var mParticle = (function () {
|
|
|
12888
13101
|
this.teardown();
|
|
12889
13102
|
}
|
|
12890
13103
|
this.hasRoktKit = options.hasRoktKit;
|
|
12891
|
-
|
|
13104
|
+
this.logButtons = options.logButtons;
|
|
13105
|
+
this.logLinks = options.logLinks;
|
|
13106
|
+
if ((!(this.logButtons || this.logLinks) || !this.eventsEnabled()) && this.isKitSuppressed()) {
|
|
12892
13107
|
this.log('opted out, not starting');
|
|
12893
13108
|
return;
|
|
12894
13109
|
}
|
|
@@ -12989,7 +13204,7 @@ var mParticle = (function () {
|
|
|
12989
13204
|
return;
|
|
12990
13205
|
}
|
|
12991
13206
|
var layer = event.type;
|
|
12992
|
-
var logsEvents = layer === 'click' && this.eventsEnabled();
|
|
13207
|
+
var logsEvents = layer === 'click' && (this.logButtons || this.logLinks) && this.eventsEnabled() && !this.hasTargetingOptOut();
|
|
12993
13208
|
var signalsKit = !this.isKitSuppressed();
|
|
12994
13209
|
if (!logsEvents && !signalsKit) {
|
|
12995
13210
|
return;
|
|
@@ -13001,9 +13216,13 @@ var mParticle = (function () {
|
|
|
13001
13216
|
// button that disables or relabels itself is seen as it was clicked.
|
|
13002
13217
|
// Logging and the kit hand-off wait for the next paint.
|
|
13003
13218
|
var click;
|
|
13219
|
+
var asLink = false;
|
|
13004
13220
|
var box;
|
|
13005
13221
|
var kind;
|
|
13006
13222
|
var source;
|
|
13223
|
+
var adds;
|
|
13224
|
+
var choice;
|
|
13225
|
+
var family;
|
|
13007
13226
|
var unconfirmedCommit = false;
|
|
13008
13227
|
if (layer === 'click') {
|
|
13009
13228
|
// The composed path is only populated during dispatch.
|
|
@@ -13011,7 +13230,18 @@ var mParticle = (function () {
|
|
|
13011
13230
|
var excluded = isExcludedPath(path);
|
|
13012
13231
|
var control = excluded ? undefined : findControl(path, true);
|
|
13013
13232
|
if (control) {
|
|
13014
|
-
|
|
13233
|
+
// With links alone, only an anchor can be logged.
|
|
13234
|
+
click = logsEvents && (this.logButtons || control.matches('a[href]')) ? describeButtonClick(control, path) : undefined;
|
|
13235
|
+
if (click) {
|
|
13236
|
+
asLink = this.logLinks && isLinkClick(click);
|
|
13237
|
+
// Without link tracking, a link that leaves the page stays a
|
|
13238
|
+
// button click, except a plain link to another page of the
|
|
13239
|
+
// site, which button tracking never logged.
|
|
13240
|
+
var asButton = this.logButtons && !asLink && !(click.linkType === 'internal' && control.matches('a[href]:not([role="button"])'));
|
|
13241
|
+
if (!asLink && !asButton) {
|
|
13242
|
+
click = undefined;
|
|
13243
|
+
}
|
|
13244
|
+
}
|
|
13015
13245
|
if (click && click.checked !== undefined) {
|
|
13016
13246
|
box = control;
|
|
13017
13247
|
}
|
|
@@ -13019,6 +13249,8 @@ var mParticle = (function () {
|
|
|
13019
13249
|
var intent = signalsKit ? classifyIntent(control, pathname) : undefined;
|
|
13020
13250
|
kind = intent ? intent.kind : undefined;
|
|
13021
13251
|
source = intent ? intent.source : undefined;
|
|
13252
|
+
adds = intent ? intent.adds : undefined;
|
|
13253
|
+
choice = signalsKit ? describePaymentChoice(control, path) : undefined;
|
|
13022
13254
|
}
|
|
13023
13255
|
this.lastClick = {
|
|
13024
13256
|
t: t,
|
|
@@ -13038,6 +13270,7 @@ var mParticle = (function () {
|
|
|
13038
13270
|
var intent = classifyIntent(control, pathname);
|
|
13039
13271
|
kind = intent ? intent.kind : undefined;
|
|
13040
13272
|
source = intent ? intent.source : undefined;
|
|
13273
|
+
adds = intent ? intent.adds : undefined;
|
|
13041
13274
|
}
|
|
13042
13275
|
unconfirmedCommit = !submitter;
|
|
13043
13276
|
}
|
|
@@ -13050,7 +13283,9 @@ var mParticle = (function () {
|
|
|
13050
13283
|
if (layer === 'blur') {
|
|
13051
13284
|
// Read after the blur settles: some browsers have not moved
|
|
13052
13285
|
// focus into the frame yet when the window blurs.
|
|
13053
|
-
|
|
13286
|
+
var frame = classifyPaymentFrame(document.activeElement, window);
|
|
13287
|
+
kind = frame ? frame.kind : undefined;
|
|
13288
|
+
family = frame ? frame.family : undefined;
|
|
13054
13289
|
source = 'frame';
|
|
13055
13290
|
} else if (unconfirmedCommit && t - _this.lastCommitClick > SUBMIT_AFTER_COMMIT_CLICK_MS) {
|
|
13056
13291
|
kind = undefined;
|
|
@@ -13064,10 +13299,17 @@ var mParticle = (function () {
|
|
|
13064
13299
|
if (box && event.defaultPrevented) {
|
|
13065
13300
|
click.checked = box.type === 'checkbox' ? !click.checked : box.checked;
|
|
13066
13301
|
}
|
|
13067
|
-
_this.logClick(click, pathname);
|
|
13302
|
+
_this.logClick(click, pathname, asLink);
|
|
13303
|
+
}
|
|
13304
|
+
// Ahead of the intent, so a pre-selection it fires goes out
|
|
13305
|
+
// with this pick.
|
|
13306
|
+
if (choice && isPicked(choice.radio)) {
|
|
13307
|
+
_this.pickPayment(t, pathname, choice.names);
|
|
13308
|
+
} else if (family) {
|
|
13309
|
+
_this.pickPayment(t, pathname, undefined, family);
|
|
13068
13310
|
}
|
|
13069
13311
|
if (kind) {
|
|
13070
|
-
_this.emit(kind, source, layer, t, pathname);
|
|
13312
|
+
_this.emit(kind, source, layer, t, pathname, adds);
|
|
13071
13313
|
}
|
|
13072
13314
|
} catch (e) {
|
|
13073
13315
|
_this.log('[error] delivery threw: ' + e);
|
|
@@ -13075,8 +13317,8 @@ var mParticle = (function () {
|
|
|
13075
13317
|
});
|
|
13076
13318
|
};
|
|
13077
13319
|
// 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()) {
|
|
13320
|
+
ButtonTracker.prototype.logClick = function (click, pathname, asLink) {
|
|
13321
|
+
if (!this.eventsEnabled() || this.hasTargetingOptOut()) {
|
|
13080
13322
|
return;
|
|
13081
13323
|
}
|
|
13082
13324
|
if (pathname !== this.pagePath) {
|
|
@@ -13090,7 +13332,7 @@ var mParticle = (function () {
|
|
|
13090
13332
|
// Restarts an expired session, as public logEvent() and page views do.
|
|
13091
13333
|
this.mpInstance._SessionManager.resetSessionTimer();
|
|
13092
13334
|
var queued = this.queuedForUpload();
|
|
13093
|
-
this.mpInstance._Events.logEvent(buildButtonClickEvent(click, pathname));
|
|
13335
|
+
this.mpInstance._Events.logEvent(asLink ? buildLinkClickEvent(click, pathname) : buildButtonClickEvent(click, pathname));
|
|
13094
13336
|
// Only a click waiting for the batch interval is sent early: a held
|
|
13095
13337
|
// one goes out when released, and with batching off it already has.
|
|
13096
13338
|
// A checkbox or radio waits for the batch, since choosing an option
|
|
@@ -13130,33 +13372,60 @@ var mParticle = (function () {
|
|
|
13130
13372
|
}
|
|
13131
13373
|
this.uploadHeld = false;
|
|
13132
13374
|
};
|
|
13133
|
-
ButtonTracker.prototype.emit = function (kind, source, layer, t, pathname) {
|
|
13375
|
+
ButtonTracker.prototype.emit = function (kind, source, layer, t, pathname, adds) {
|
|
13134
13376
|
if (this.isKitSuppressed()) {
|
|
13135
13377
|
return;
|
|
13136
13378
|
}
|
|
13137
13379
|
if (kind === 'commit' && layer === 'click') {
|
|
13138
13380
|
this.lastCommitClick = t;
|
|
13139
13381
|
}
|
|
13140
|
-
|
|
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];
|
|
13141
13386
|
if (last && last.pathname === pathname && t - last.t < THROTTLE_MS) {
|
|
13142
13387
|
return;
|
|
13143
13388
|
}
|
|
13144
|
-
this.lastSent[
|
|
13389
|
+
this.lastSent[key] = {
|
|
13145
13390
|
t: t,
|
|
13146
13391
|
pathname: pathname
|
|
13147
13392
|
};
|
|
13148
|
-
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
|
+
} : {
|
|
13149
13400
|
kind: kind,
|
|
13150
13401
|
t: t,
|
|
13151
13402
|
source: source,
|
|
13152
13403
|
pathname: pathname
|
|
13153
13404
|
}), pathname);
|
|
13154
13405
|
};
|
|
13406
|
+
ButtonTracker.prototype.pickPayment = function (t, pathname, names, family) {
|
|
13407
|
+
if (this.isKitSuppressed()) {
|
|
13408
|
+
return;
|
|
13409
|
+
}
|
|
13410
|
+
this.mpInstance._RoktManager.notifyPaymentPick(Object.freeze({
|
|
13411
|
+
t: t,
|
|
13412
|
+
pathname: pathname,
|
|
13413
|
+
names: names ? Object.freeze(names.slice()) : undefined,
|
|
13414
|
+
family: family
|
|
13415
|
+
}));
|
|
13416
|
+
};
|
|
13155
13417
|
// Events follow the SDK's opt-out like any other event.
|
|
13156
13418
|
ButtonTracker.prototype.eventsEnabled = function () {
|
|
13157
13419
|
var store = this.mpInstance._Store;
|
|
13158
13420
|
return !!store && store.isEnabled;
|
|
13159
13421
|
};
|
|
13422
|
+
// Read per click, since the launcher options can arrive after the tracker
|
|
13423
|
+
// starts. Only where this init configures a Rokt kit, so Global Privacy
|
|
13424
|
+
// Control alone doesn't stop click logging elsewhere.
|
|
13425
|
+
ButtonTracker.prototype.hasTargetingOptOut = function () {
|
|
13426
|
+
var roktManager = this.mpInstance._RoktManager;
|
|
13427
|
+
return this.hasRoktKit && !!roktManager && roktManager.hasTargetingOptOut();
|
|
13428
|
+
};
|
|
13160
13429
|
// The Rokt manager owns the kit's privacy gates: flag, opt-out, launcher
|
|
13161
13430
|
// options and Global Privacy Control.
|
|
13162
13431
|
ButtonTracker.prototype.isKitSuppressed = function () {
|
|
@@ -14101,7 +14370,8 @@ var mParticle = (function () {
|
|
|
14101
14370
|
var getFeatureFlag = mpInstance._Helpers.getFeatureFlag;
|
|
14102
14371
|
var _e = Constants.FeatureFlags,
|
|
14103
14372
|
AutoLogPageView = _e.AutoLogPageView,
|
|
14104
|
-
AutoButtonTracking = _e.AutoButtonTracking
|
|
14373
|
+
AutoButtonTracking = _e.AutoButtonTracking,
|
|
14374
|
+
AutoLinkTracking = _e.AutoLinkTracking;
|
|
14105
14375
|
// Destroy previous batch uploader to prevent leaked timers and event listeners
|
|
14106
14376
|
if ((_a = mpInstance._APIClient) === null || _a === void 0 ? void 0 : _a.uploader) {
|
|
14107
14377
|
mpInstance._APIClient.uploader.destroy();
|
|
@@ -14168,11 +14438,16 @@ var mParticle = (function () {
|
|
|
14168
14438
|
// Rokt kit only when that kit receives them. Set before
|
|
14169
14439
|
// processForwarders: the kit can read it during this init, from its own
|
|
14170
14440
|
// init or from a returning shopper's landing page view.
|
|
14441
|
+
var logButtons = !!getFeatureFlag(AutoButtonTracking);
|
|
14442
|
+
var logLinks = !!getFeatureFlag(AutoLinkTracking);
|
|
14443
|
+
// Links feed intent too, so with link tracking on the kit must also
|
|
14444
|
+
// receive Auto Link Click events.
|
|
14171
14445
|
var buttonClickBlocker = roktConfig_1 ? getButtonClickBlocker(roktConfig_1, kitBlocker) : undefined;
|
|
14172
|
-
|
|
14173
|
-
|
|
14446
|
+
var linkClickBlocker = roktConfig_1 && logLinks ? getButtonClickBlocker(roktConfig_1, kitBlocker, true) : undefined;
|
|
14447
|
+
if (logButtons && (buttonClickBlocker || linkClickBlocker)) {
|
|
14448
|
+
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
14449
|
}
|
|
14175
|
-
mpInstance._RoktManager.setAutoButtonClicksForwarded(!!roktConfig_1 && !buttonClickBlocker);
|
|
14450
|
+
mpInstance._RoktManager.setAutoButtonClicksForwarded(!!roktConfig_1 && !buttonClickBlocker && !linkClickBlocker);
|
|
14176
14451
|
mpInstance._Forwarders.processForwarders(config, mpInstance._APIClient.prepareForwardingStats);
|
|
14177
14452
|
mpInstance._Forwarders.processPixelConfigs(config);
|
|
14178
14453
|
// Checks if session is created, resumed, or needs to be ended
|
|
@@ -14207,12 +14482,14 @@ var mParticle = (function () {
|
|
|
14207
14482
|
// so it stops listening. Re-created if the flag is re-enabled later.
|
|
14208
14483
|
mpInstance._PageViewTracker.teardown();
|
|
14209
14484
|
}
|
|
14210
|
-
if (
|
|
14485
|
+
if (logButtons || logLinks) {
|
|
14211
14486
|
if (!mpInstance._ButtonTracker) {
|
|
14212
14487
|
mpInstance._ButtonTracker = new ButtonTracker(mpInstance);
|
|
14213
14488
|
}
|
|
14214
14489
|
mpInstance._ButtonTracker.init({
|
|
14215
|
-
hasRoktKit: !!roktConfig_1
|
|
14490
|
+
hasRoktKit: !!roktConfig_1,
|
|
14491
|
+
logButtons: logButtons,
|
|
14492
|
+
logLinks: logLinks
|
|
14216
14493
|
});
|
|
14217
14494
|
} else {
|
|
14218
14495
|
// Also retires a tracker left by an earlier bundle load. Like APV,
|
|
@@ -14318,10 +14595,12 @@ var mParticle = (function () {
|
|
|
14318
14595
|
// Initialize CookieConsentManager with privacy flags from launcherOptions
|
|
14319
14596
|
var _a = normalizeRoktLauncherOptions(config === null || config === void 0 ? void 0 : config.launcherOptions),
|
|
14320
14597
|
noFunctional = _a.noFunctional,
|
|
14321
|
-
noTargeting = _a.noTargeting
|
|
14598
|
+
noTargeting = _a.noTargeting,
|
|
14599
|
+
doNotShareOrSell = _a.doNotShareOrSell;
|
|
14322
14600
|
mpInstance._CookieConsentManager = new CookieConsentManager({
|
|
14323
14601
|
noFunctional: noFunctional,
|
|
14324
|
-
noTargeting: noTargeting
|
|
14602
|
+
noTargeting: noTargeting,
|
|
14603
|
+
doNotShareOrSell: doNotShareOrSell
|
|
14325
14604
|
});
|
|
14326
14605
|
// Check to see if localStorage is available before main configuration runs
|
|
14327
14606
|
// since we will need this for the current implementation of user persistence
|