@pendo/agent 2.291.4 → 2.292.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/debugger-plugin.min.js +1 -1
- package/dist/dom.esm.js +14 -3
- package/dist/pendo.debugger.min.js +9 -8
- package/dist/pendo.module.js +421 -292
- package/dist/pendo.module.min.js +9 -9
- package/dist/pendo.preview.min.js +3 -3
- package/package.json +1 -1
package/dist/pendo.module.js
CHANGED
|
@@ -463,6 +463,9 @@ function shouldUseUnminifiedAgent(config, debuggingEnabled) {
|
|
|
463
463
|
return !isExtension(config) && isMinifiedAgent(config) && debuggingEnabled;
|
|
464
464
|
}
|
|
465
465
|
function findAgentScriptTag(scripts = [], apiKey) {
|
|
466
|
+
if (document.currentScript) {
|
|
467
|
+
return document.currentScript;
|
|
468
|
+
}
|
|
466
469
|
const regex = /^https:\/\/[\w\-.]*cdn[\w\-.]*\.(pendo-dev\.com|pendo\.io)\/agent\/static\/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}|PENDO_API_KEY)\/pendo\.js$/g;
|
|
467
470
|
for (let i = 0; i < scripts.length; i++) {
|
|
468
471
|
const script = scripts[i];
|
|
@@ -3687,6 +3690,10 @@ function globalBucket(env) {
|
|
|
3687
3690
|
}
|
|
3688
3691
|
|
|
3689
3692
|
function isNativeCode(fn) { return /native/.test(fn); }
|
|
3693
|
+
const detectNativeBrowserAPI = (name) => {
|
|
3694
|
+
const fn = _.get(window, name);
|
|
3695
|
+
return (fn && isNativeCode(fn));
|
|
3696
|
+
};
|
|
3690
3697
|
|
|
3691
3698
|
var isOldIE = function (olderThan, tVersion) {
|
|
3692
3699
|
olderThan = olderThan || 10;
|
|
@@ -3904,8 +3911,8 @@ var SERVER = '';
|
|
|
3904
3911
|
var ASSET_HOST = '';
|
|
3905
3912
|
var ASSET_PATH = '';
|
|
3906
3913
|
var DESIGNER_SERVER = '';
|
|
3907
|
-
var VERSION = '2.
|
|
3908
|
-
var PACKAGE_VERSION = '2.
|
|
3914
|
+
var VERSION = '2.292.0_';
|
|
3915
|
+
var PACKAGE_VERSION = '2.292.0';
|
|
3909
3916
|
var LOADER = 'xhr';
|
|
3910
3917
|
/* eslint-enable agent-eslint-rules/no-gulp-env-references */
|
|
3911
3918
|
/**
|
|
@@ -10133,6 +10140,17 @@ var removeNode = function (domNode) {
|
|
|
10133
10140
|
domNode.parentNode.removeChild(domNode);
|
|
10134
10141
|
}
|
|
10135
10142
|
};
|
|
10143
|
+
var getElements = _.compose(function (arrLike) {
|
|
10144
|
+
return Array.prototype.slice.call(arrLike);
|
|
10145
|
+
}, function (tag, document) {
|
|
10146
|
+
try {
|
|
10147
|
+
return SizzleProxy(tag, document);
|
|
10148
|
+
}
|
|
10149
|
+
catch (e) {
|
|
10150
|
+
writeMessage('error using sizzle: ' + e);
|
|
10151
|
+
return document.getElementsByTagName(tag);
|
|
10152
|
+
}
|
|
10153
|
+
});
|
|
10136
10154
|
var pickBestBODY = function (b1, b2) {
|
|
10137
10155
|
try {
|
|
10138
10156
|
// check children.length, check Height, check Width?
|
|
@@ -10146,9 +10164,10 @@ var pickBestBODY = function (b1, b2) {
|
|
|
10146
10164
|
return 0;
|
|
10147
10165
|
}
|
|
10148
10166
|
};
|
|
10149
|
-
var getBody = function (_document
|
|
10167
|
+
var getBody = function (_document) {
|
|
10168
|
+
_document = _document || document;
|
|
10150
10169
|
try {
|
|
10151
|
-
var bds =
|
|
10170
|
+
var bds = getElements('body', _document);
|
|
10152
10171
|
if (bds && bds.length > 1) {
|
|
10153
10172
|
bds.sort(pickBestBODY);
|
|
10154
10173
|
return bds[0] || _document.body;
|
|
@@ -12184,6 +12203,92 @@ class LocalStorageEventBuffer {
|
|
|
12184
12203
|
}
|
|
12185
12204
|
var localStorageEventBuffer = new LocalStorageEventBuffer();
|
|
12186
12205
|
|
|
12206
|
+
class PerformanceMonitor {
|
|
12207
|
+
constructor() {
|
|
12208
|
+
this._isPerformanceApiAvailable = this._checkPerformanceApi();
|
|
12209
|
+
this._measuringPerformance = false;
|
|
12210
|
+
this._marks = {};
|
|
12211
|
+
this._measures = {};
|
|
12212
|
+
}
|
|
12213
|
+
initialize() {
|
|
12214
|
+
this._measuringPerformance = true;
|
|
12215
|
+
this._markPerformance('initialize');
|
|
12216
|
+
// temporary clear interval while working on send implementation
|
|
12217
|
+
this.interval = setInterval(() => {
|
|
12218
|
+
this._clearMarksAndMeasures();
|
|
12219
|
+
}, 1000 * 60 * 10);
|
|
12220
|
+
return () => {
|
|
12221
|
+
this.teardown();
|
|
12222
|
+
};
|
|
12223
|
+
}
|
|
12224
|
+
teardown() {
|
|
12225
|
+
this._measuringPerformance = false;
|
|
12226
|
+
this._markPerformance('teardown');
|
|
12227
|
+
this._clearMarksAndMeasures();
|
|
12228
|
+
clearInterval(this.interval);
|
|
12229
|
+
}
|
|
12230
|
+
startTimer(name) {
|
|
12231
|
+
this._markPerformance(`${name}-start`);
|
|
12232
|
+
}
|
|
12233
|
+
stopTimer(name) {
|
|
12234
|
+
this._markPerformance(`${name}-stop`);
|
|
12235
|
+
this._measurePerformance(name);
|
|
12236
|
+
}
|
|
12237
|
+
track(name) {
|
|
12238
|
+
this._markPerformance(name);
|
|
12239
|
+
}
|
|
12240
|
+
send() {
|
|
12241
|
+
performance.getEntries();
|
|
12242
|
+
// TODO: implement filter/send process
|
|
12243
|
+
this._clearMarksAndMeasures();
|
|
12244
|
+
}
|
|
12245
|
+
_checkPerformanceApi() {
|
|
12246
|
+
return detectNativeBrowserAPI('performance.mark') &&
|
|
12247
|
+
detectNativeBrowserAPI('performance.measure') &&
|
|
12248
|
+
detectNativeBrowserAPI('performance.getEntries') &&
|
|
12249
|
+
detectNativeBrowserAPI('performance.clearMarks') &&
|
|
12250
|
+
detectNativeBrowserAPI('performance.clearMeasures');
|
|
12251
|
+
}
|
|
12252
|
+
_shouldMeasurePerformance() {
|
|
12253
|
+
return this._isPerformanceApiAvailable && this._measuringPerformance;
|
|
12254
|
+
}
|
|
12255
|
+
_markPerformance(name) {
|
|
12256
|
+
if (!this._shouldMeasurePerformance())
|
|
12257
|
+
return;
|
|
12258
|
+
name = `pendo-${name}`;
|
|
12259
|
+
performance.mark(name);
|
|
12260
|
+
this._count(this._marks, name);
|
|
12261
|
+
}
|
|
12262
|
+
_measurePerformance(name) {
|
|
12263
|
+
if (!this._shouldMeasurePerformance())
|
|
12264
|
+
return;
|
|
12265
|
+
name = `pendo-${name}`;
|
|
12266
|
+
const startMark = `${name}-start`;
|
|
12267
|
+
const stopMark = `${name}-stop`;
|
|
12268
|
+
performance.measure(name, startMark, stopMark);
|
|
12269
|
+
this._count(this._measures, name);
|
|
12270
|
+
}
|
|
12271
|
+
_count(registry, name) {
|
|
12272
|
+
if (!registry[name]) {
|
|
12273
|
+
registry[name] = 1;
|
|
12274
|
+
}
|
|
12275
|
+
else {
|
|
12276
|
+
registry[name]++;
|
|
12277
|
+
}
|
|
12278
|
+
}
|
|
12279
|
+
_clearMarksAndMeasures() {
|
|
12280
|
+
_.each(this._marks, (count, name) => {
|
|
12281
|
+
performance.clearMarks(name);
|
|
12282
|
+
});
|
|
12283
|
+
_.each(this._measures, (count, name) => {
|
|
12284
|
+
performance.clearMeasures(name);
|
|
12285
|
+
});
|
|
12286
|
+
this._marks = {};
|
|
12287
|
+
this._measures = {};
|
|
12288
|
+
}
|
|
12289
|
+
}
|
|
12290
|
+
var PerformanceMonitor$1 = new PerformanceMonitor();
|
|
12291
|
+
|
|
12187
12292
|
var defaultTrackName = '_PENDO_UNNAMED_';
|
|
12188
12293
|
var SILO_AVG_COMPRESSION_RATIO = 5;
|
|
12189
12294
|
/**
|
|
@@ -12245,21 +12350,7 @@ function collectEvent(type, props, url, name, eventProperties, context) {
|
|
|
12245
12350
|
agenticEventQueue.push(event);
|
|
12246
12351
|
return;
|
|
12247
12352
|
}
|
|
12248
|
-
eventQueue.push(
|
|
12249
|
-
}
|
|
12250
|
-
function attachMonitoringData(store, event) {
|
|
12251
|
-
try {
|
|
12252
|
-
if (!store.getters['monitoring/shouldFlush']())
|
|
12253
|
-
return event;
|
|
12254
|
-
var payload = store.getters['monitoring/payload']();
|
|
12255
|
-
store.dispatch('monitoring/flush');
|
|
12256
|
-
if (!_.isEmpty(payload)) {
|
|
12257
|
-
event.ops = payload;
|
|
12258
|
-
}
|
|
12259
|
-
}
|
|
12260
|
-
catch (e) {
|
|
12261
|
-
}
|
|
12262
|
-
return event;
|
|
12353
|
+
eventQueue.push(event);
|
|
12263
12354
|
}
|
|
12264
12355
|
// @const {Event.type[]}
|
|
12265
12356
|
var WHITELIST_FREE_NPS = ['load', 'meta', 'identify'];
|
|
@@ -12698,7 +12789,7 @@ function createSendQueue(options, send, guaranteedSend) {
|
|
|
12698
12789
|
}
|
|
12699
12790
|
});
|
|
12700
12791
|
queue.onTimeout = function () {
|
|
12701
|
-
|
|
12792
|
+
PerformanceMonitor$1.track(`${options.beacon}-gif-failure`);
|
|
12702
12793
|
};
|
|
12703
12794
|
queue.retryPending = true;
|
|
12704
12795
|
return queue;
|
|
@@ -12990,7 +13081,7 @@ var handleEmbeddedData = function (src) {
|
|
|
12990
13081
|
return src + '';
|
|
12991
13082
|
};
|
|
12992
13083
|
function getAttributeValue(element, attrName) {
|
|
12993
|
-
return
|
|
13084
|
+
return store.getters['nodeAttr/getAttribute']()(element, attrName);
|
|
12994
13085
|
}
|
|
12995
13086
|
var extractAttribute = function (element, attrName, type) {
|
|
12996
13087
|
if (!element || !element.nodeName)
|
|
@@ -21042,10 +21133,6 @@ class UpdateRunner {
|
|
|
21042
21133
|
}
|
|
21043
21134
|
}
|
|
21044
21135
|
complete(time) {
|
|
21045
|
-
store.commit('monitoring/setTimer', {
|
|
21046
|
-
name: 'guideUpdateTimeMS',
|
|
21047
|
-
time: this.updateTotalTime
|
|
21048
|
-
});
|
|
21049
21136
|
store.commit('guideUpdate/completeUpdate', time);
|
|
21050
21137
|
this.cancel();
|
|
21051
21138
|
}
|
|
@@ -23917,13 +24004,8 @@ class GuideCache {
|
|
|
23917
24004
|
return;
|
|
23918
24005
|
cachedStep.seenState = lastGuideStepSeen.state;
|
|
23919
24006
|
cachedStep.seenReason = lastGuideStepSeen.seenReason;
|
|
23920
|
-
cachedStep.
|
|
23921
|
-
|
|
23922
|
-
cachedStep.dismissCount = lastGuideStepSeen.dismissCount;
|
|
23923
|
-
}
|
|
23924
|
-
if (lastGuideStepSeen.snoozeEndTime != null) {
|
|
23925
|
-
cachedStep.snoozeEndTime = lastGuideStepSeen.snoozeEndTime;
|
|
23926
|
-
}
|
|
24007
|
+
cachedStep.dismissCount = lastGuideStepSeen.dismissCount;
|
|
24008
|
+
cachedStep.snoozeEndTime = lastGuideStepSeen.snoozeEndTime;
|
|
23927
24009
|
return this.save(cachedGuide);
|
|
23928
24010
|
}
|
|
23929
24011
|
list(visitorId, now = getNow()) {
|
|
@@ -26533,6 +26615,11 @@ var EventRouter = function () {
|
|
|
26533
26615
|
var config = configParam.value;
|
|
26534
26616
|
var cases = casesParam.value;
|
|
26535
26617
|
var conditionResult = evaluateCondition(conditionType, config);
|
|
26618
|
+
Events.trigger('appUsage', {
|
|
26619
|
+
type: 'conditionalSplitResult',
|
|
26620
|
+
elementId: evt.srcElement.id,
|
|
26621
|
+
conditionResult
|
|
26622
|
+
});
|
|
26536
26623
|
var matchingCase = _.find(cases, function (caseItem) {
|
|
26537
26624
|
return caseItem.value === conditionResult;
|
|
26538
26625
|
});
|
|
@@ -26600,16 +26687,27 @@ var GuideActivity = (function () {
|
|
|
26600
26687
|
var isObject = _.isObject;
|
|
26601
26688
|
var findWhere = _.findWhere;
|
|
26602
26689
|
const _guideResolvers = [];
|
|
26690
|
+
var conditionalSplitEventQueue = [];
|
|
26603
26691
|
return {
|
|
26604
26692
|
type: GA_TYPE,
|
|
26605
26693
|
handler(evtData) {
|
|
26606
26694
|
var appData = evtData.data[0];
|
|
26695
|
+
if (appData && appData.type === 'conditionalSplitResult') {
|
|
26696
|
+
finalizeConditionalSplitEvent(appData);
|
|
26697
|
+
return;
|
|
26698
|
+
}
|
|
26607
26699
|
var browserEvt = evtData.data[1];
|
|
26608
26700
|
if (!shouldHandleEvent(appData, browserEvt))
|
|
26609
26701
|
return;
|
|
26610
26702
|
var activityEvent = transformToGuideActivity(appData);
|
|
26611
26703
|
if (activityEvent) {
|
|
26612
|
-
|
|
26704
|
+
const firstAction = _.get(activityEvent, ['props', 'ui_element_actions', 0, 'action']);
|
|
26705
|
+
if (firstAction === 'conditionalSplit') {
|
|
26706
|
+
conditionalSplitEventQueue.push(activityEvent);
|
|
26707
|
+
}
|
|
26708
|
+
else {
|
|
26709
|
+
stageGuideEvent(activityEvent);
|
|
26710
|
+
}
|
|
26613
26711
|
}
|
|
26614
26712
|
},
|
|
26615
26713
|
registerGuideResolver(callBack) {
|
|
@@ -26622,6 +26720,22 @@ var GuideActivity = (function () {
|
|
|
26622
26720
|
}
|
|
26623
26721
|
}
|
|
26624
26722
|
};
|
|
26723
|
+
function finalizeConditionalSplitEvent(evtData) {
|
|
26724
|
+
const { conditionResult, elementId } = evtData;
|
|
26725
|
+
const matchingEventIndex = _.findIndex(conditionalSplitEventQueue, (event) => {
|
|
26726
|
+
return event.props.ui_element_id === elementId;
|
|
26727
|
+
});
|
|
26728
|
+
if (matchingEventIndex === -1)
|
|
26729
|
+
return;
|
|
26730
|
+
const matchingEvent = conditionalSplitEventQueue.splice(matchingEventIndex, 1)[0];
|
|
26731
|
+
const conditionalSplitAction = matchingEvent.props.ui_element_actions[0];
|
|
26732
|
+
conditionalSplitAction.condition_result = conditionResult;
|
|
26733
|
+
const cases = conditionalSplitAction.cases;
|
|
26734
|
+
const resultCase = cases[conditionResult];
|
|
26735
|
+
matchingEvent.props.ui_element_actions = matchingEvent.props.ui_element_actions.concat(resultCase);
|
|
26736
|
+
delete conditionalSplitAction.cases;
|
|
26737
|
+
stageGuideEvent(matchingEvent);
|
|
26738
|
+
}
|
|
26625
26739
|
function isClickEvent(browserEvt) {
|
|
26626
26740
|
return browserEvt && browserEvt.type === 'click';
|
|
26627
26741
|
}
|
|
@@ -26738,58 +26852,7 @@ var GuideActivity = (function () {
|
|
|
26738
26852
|
];
|
|
26739
26853
|
}
|
|
26740
26854
|
if (element.actions !== undefined) {
|
|
26741
|
-
return _.map(element.actions,
|
|
26742
|
-
switch (action.action) {
|
|
26743
|
-
case 'automation':
|
|
26744
|
-
var automationIds = findWhere(action.parameters, { name: 'automationIds' });
|
|
26745
|
-
return {
|
|
26746
|
-
action: action.action,
|
|
26747
|
-
automationIds
|
|
26748
|
-
};
|
|
26749
|
-
case 'openLink':
|
|
26750
|
-
var url = findWhere(action.parameters, { name: 'url' });
|
|
26751
|
-
var target = findWhere(action.parameters, { name: 'target' });
|
|
26752
|
-
return {
|
|
26753
|
-
action: action.action,
|
|
26754
|
-
url: sanitizeUrl(url.value),
|
|
26755
|
-
target: target.value
|
|
26756
|
-
};
|
|
26757
|
-
case 'submitPollAndGoToStep':
|
|
26758
|
-
case 'goToStep':
|
|
26759
|
-
var guideStepId = findWhere(action.parameters, { name: 'goToStepId' });
|
|
26760
|
-
return {
|
|
26761
|
-
action: action.action,
|
|
26762
|
-
guideStepId: guideStepId.value
|
|
26763
|
-
};
|
|
26764
|
-
case 'guideSnoozed':
|
|
26765
|
-
var duration = findWhere(action.parameters, { name: 'snooze_duration' });
|
|
26766
|
-
var timeUnit = findWhere(action.parameters, { name: 'time_unit' });
|
|
26767
|
-
return {
|
|
26768
|
-
action: action.action,
|
|
26769
|
-
duration: duration.value,
|
|
26770
|
-
timeUnit: timeUnit.value
|
|
26771
|
-
};
|
|
26772
|
-
case 'showGuide':
|
|
26773
|
-
case 'launchGuide':
|
|
26774
|
-
var guideId = action.parameters[0];
|
|
26775
|
-
var stepId = action.parameters[1] || {};
|
|
26776
|
-
return {
|
|
26777
|
-
action: action.action,
|
|
26778
|
-
guideId: guideId.value,
|
|
26779
|
-
stepId: stepId.value
|
|
26780
|
-
};
|
|
26781
|
-
case 'advanceGuide':
|
|
26782
|
-
case 'previousStep':
|
|
26783
|
-
case 'submitPoll':
|
|
26784
|
-
case 'dismissGuide':
|
|
26785
|
-
case 'confirmation':
|
|
26786
|
-
return {
|
|
26787
|
-
action: action.action
|
|
26788
|
-
};
|
|
26789
|
-
default:
|
|
26790
|
-
return {};
|
|
26791
|
-
}
|
|
26792
|
-
});
|
|
26855
|
+
return _.map(element.actions, processAction);
|
|
26793
26856
|
}
|
|
26794
26857
|
if (uiElement.templateName === 'pendo_task_list_item') {
|
|
26795
26858
|
if (_.isArray(element.templateChildren) && element.templateChildren[uiElement.templateChildIndex]) {
|
|
@@ -26801,6 +26864,79 @@ var GuideActivity = (function () {
|
|
|
26801
26864
|
}
|
|
26802
26865
|
return [];
|
|
26803
26866
|
}
|
|
26867
|
+
function processAction(action) {
|
|
26868
|
+
switch (action.action) {
|
|
26869
|
+
case 'automation':
|
|
26870
|
+
var automationIds = findWhere(action.parameters, { name: 'automationIds' });
|
|
26871
|
+
return {
|
|
26872
|
+
action: action.action,
|
|
26873
|
+
automationIds
|
|
26874
|
+
};
|
|
26875
|
+
case 'openLink':
|
|
26876
|
+
var url = findWhere(action.parameters, { name: 'url' });
|
|
26877
|
+
var target = findWhere(action.parameters, { name: 'target' });
|
|
26878
|
+
return {
|
|
26879
|
+
action: action.action,
|
|
26880
|
+
url: sanitizeUrl(url.value),
|
|
26881
|
+
target: target.value
|
|
26882
|
+
};
|
|
26883
|
+
case 'submitPollAndGoToStep':
|
|
26884
|
+
case 'goToStep':
|
|
26885
|
+
var guideStepId = findWhere(action.parameters, { name: 'goToStepId' });
|
|
26886
|
+
return {
|
|
26887
|
+
action: action.action,
|
|
26888
|
+
guideStepId: guideStepId.value
|
|
26889
|
+
};
|
|
26890
|
+
case 'guideSnoozed':
|
|
26891
|
+
var duration = findWhere(action.parameters, { name: 'snooze_duration' });
|
|
26892
|
+
var timeUnit = findWhere(action.parameters, { name: 'time_unit' });
|
|
26893
|
+
return {
|
|
26894
|
+
action: action.action,
|
|
26895
|
+
duration: duration.value,
|
|
26896
|
+
timeUnit: timeUnit.value
|
|
26897
|
+
};
|
|
26898
|
+
case 'showGuide':
|
|
26899
|
+
case 'launchGuide':
|
|
26900
|
+
var guideId = action.parameters[0];
|
|
26901
|
+
var stepId = action.parameters[1] || {};
|
|
26902
|
+
return {
|
|
26903
|
+
action: action.action,
|
|
26904
|
+
guideId: guideId.value,
|
|
26905
|
+
stepId: stepId.value
|
|
26906
|
+
};
|
|
26907
|
+
case 'conditionalSplit':
|
|
26908
|
+
var name = findWhere(action.parameters, { name: 'name' });
|
|
26909
|
+
var conditionType = findWhere(action.parameters, { name: 'conditionType' });
|
|
26910
|
+
var config = findWhere(action.parameters, { name: 'config' });
|
|
26911
|
+
var cases = findWhere(action.parameters, { name: 'cases' });
|
|
26912
|
+
var processedCases = _.reduce(cases.value, function (acc, c) {
|
|
26913
|
+
acc[c.value] = _.map(c.actions, function (a) {
|
|
26914
|
+
var processedAction = processAction(a);
|
|
26915
|
+
processedAction.source = a.source;
|
|
26916
|
+
return processedAction;
|
|
26917
|
+
});
|
|
26918
|
+
return acc;
|
|
26919
|
+
}, {});
|
|
26920
|
+
return {
|
|
26921
|
+
action: action.action,
|
|
26922
|
+
name: name.value,
|
|
26923
|
+
condition_type: conditionType.value,
|
|
26924
|
+
element_selector: config.value.elementSelector,
|
|
26925
|
+
feature_id: config.value.featureId,
|
|
26926
|
+
cases: processedCases // will be removed in finalizeConditionalSplitEvent
|
|
26927
|
+
};
|
|
26928
|
+
case 'advanceGuide':
|
|
26929
|
+
case 'previousStep':
|
|
26930
|
+
case 'submitPoll':
|
|
26931
|
+
case 'dismissGuide':
|
|
26932
|
+
case 'confirmation':
|
|
26933
|
+
return {
|
|
26934
|
+
action: action.action
|
|
26935
|
+
};
|
|
26936
|
+
default:
|
|
26937
|
+
return {};
|
|
26938
|
+
}
|
|
26939
|
+
}
|
|
26804
26940
|
function transformToGuideActivity(appData) {
|
|
26805
26941
|
var activeGuideObj = getGuideForEvent(appData);
|
|
26806
26942
|
if (!activeGuideObj)
|
|
@@ -26999,14 +27135,14 @@ var didAccountIdentityChange = function (props) {
|
|
|
26999
27135
|
function initIdentityEvents() {
|
|
27000
27136
|
if (initialized)
|
|
27001
27137
|
return;
|
|
27002
|
-
|
|
27138
|
+
const collectIdentifyEvent = function (event) {
|
|
27003
27139
|
var props = event.data[0];
|
|
27004
27140
|
if (wasAnonymousVisitorIdentified(props) || didAccountIdentityChange(props)) {
|
|
27005
27141
|
collectEvent('identify', props);
|
|
27006
27142
|
flushLater(); // unconditionally on next tick
|
|
27007
27143
|
}
|
|
27008
|
-
}
|
|
27009
|
-
|
|
27144
|
+
};
|
|
27145
|
+
const collectMetadataEvent = function (event) {
|
|
27010
27146
|
// Check to see if this Application is sending metadata to the backend using
|
|
27011
27147
|
// different mechanism (like Segment webhooks)
|
|
27012
27148
|
var blockAgentMetadata = isMetadataBlocked();
|
|
@@ -27017,9 +27153,17 @@ function initIdentityEvents() {
|
|
|
27017
27153
|
flushLater(); // unconditionally on next tick
|
|
27018
27154
|
}
|
|
27019
27155
|
}
|
|
27020
|
-
}
|
|
27156
|
+
};
|
|
27157
|
+
Events.identify.on(collectIdentifyEvent);
|
|
27158
|
+
Events.metadata.on(collectMetadataEvent);
|
|
27021
27159
|
Events.identify.on(handleIdentifyEvent);
|
|
27022
27160
|
initialized = true;
|
|
27161
|
+
return function () {
|
|
27162
|
+
Events.identify.off(collectIdentifyEvent);
|
|
27163
|
+
Events.metadata.off(collectMetadataEvent);
|
|
27164
|
+
Events.identify.off(handleIdentifyEvent);
|
|
27165
|
+
initialized = false;
|
|
27166
|
+
};
|
|
27023
27167
|
}
|
|
27024
27168
|
|
|
27025
27169
|
/*
|
|
@@ -27230,7 +27374,7 @@ class ShadowDomManager extends EventTarget {
|
|
|
27230
27374
|
}
|
|
27231
27375
|
initialize() {
|
|
27232
27376
|
this.unpatchAttachShadow = this.patchAttachShadow(Element);
|
|
27233
|
-
this.findShadowRoots(document);
|
|
27377
|
+
this.findShadowRoots(document, 5000, (shadowRoot) => this.triggerAttachShadow(shadowRoot));
|
|
27234
27378
|
}
|
|
27235
27379
|
triggerAttachShadow(shadowRoot) {
|
|
27236
27380
|
this.cache.add(shadowRoot);
|
|
@@ -27239,7 +27383,7 @@ class ShadowDomManager extends EventTarget {
|
|
|
27239
27383
|
shadowRoot
|
|
27240
27384
|
});
|
|
27241
27385
|
}
|
|
27242
|
-
findShadowRoots(document, maxPerSearch = 5000) {
|
|
27386
|
+
findShadowRoots(document, maxPerSearch = 5000, onShadowRootFound) {
|
|
27243
27387
|
if (!_.isFunction(document.createNodeIterator))
|
|
27244
27388
|
return;
|
|
27245
27389
|
let nodesChecked = 0;
|
|
@@ -27255,7 +27399,7 @@ class ShadowDomManager extends EventTarget {
|
|
|
27255
27399
|
while ((currentNode = iterator.nextNode())) {
|
|
27256
27400
|
nodesChecked++;
|
|
27257
27401
|
if (currentNode && currentNode.shadowRoot) {
|
|
27258
|
-
|
|
27402
|
+
onShadowRootFound(currentNode.shadowRoot);
|
|
27259
27403
|
queue.push(currentNode.shadowRoot);
|
|
27260
27404
|
this.foundShadowRoots = true;
|
|
27261
27405
|
}
|
|
@@ -27376,7 +27520,8 @@ function registerEventHandlers({ events = [] }) {
|
|
|
27376
27520
|
let initializeCounter = 0;
|
|
27377
27521
|
const initializeImmediately = 'initializeImmediately';
|
|
27378
27522
|
/**
|
|
27379
|
-
* Initializes the Pendo
|
|
27523
|
+
* Initializes the Pendo agent in a browser window. This function only needs to be called once per page load. Any subsequent calls, without first having called `teardown`, will be ignored.
|
|
27524
|
+
* Once the agent has been initialized, any updates to identity or metadata should be done using `identify` or `updateOptions`.
|
|
27380
27525
|
*
|
|
27381
27526
|
* @access public
|
|
27382
27527
|
* @function
|
|
@@ -27522,13 +27667,14 @@ const initialize = makeSafe(function (options) {
|
|
|
27522
27667
|
teardownFns.push(forwardInternalEvents(Events));
|
|
27523
27668
|
registerEventHandlers(options);
|
|
27524
27669
|
teardownFns.push(initGuides(observer)); // this is safe. loadGuides actually does the loading.
|
|
27525
|
-
initIdentityEvents(); // setup identify and meta event listeners
|
|
27670
|
+
teardownFns.push(initIdentityEvents()); // setup identify and meta event listeners
|
|
27526
27671
|
teardownFns.push(wirePage());
|
|
27527
27672
|
teardownFns.push(initializePlugins());
|
|
27528
27673
|
teardownFns.push(launchDesignerOrPreview(options));
|
|
27529
27674
|
Events.appUsage.on(GuideActivity.handler);
|
|
27530
27675
|
Events.appUsage.on(ResourceCenterActivity.handler);
|
|
27531
27676
|
teardownFns.push(flushEvery(SEND_INTERVAL));
|
|
27677
|
+
teardownFns.push(PerformanceMonitor$1.initialize());
|
|
27532
27678
|
}
|
|
27533
27679
|
Events.appHidden.on(() => {
|
|
27534
27680
|
flushNow(true, { hidden: true });
|
|
@@ -29021,11 +29167,14 @@ var attrActionEnum = {
|
|
|
29021
29167
|
href: ['Replace', 'ForceSecure'],
|
|
29022
29168
|
protocol: ['ForceSecure']
|
|
29023
29169
|
};
|
|
29024
|
-
|
|
29170
|
+
const TARGETS = ['location', 'attribute', 'both'];
|
|
29171
|
+
const DEFAULT_TARGET = 'location';
|
|
29172
|
+
function UrlTransform(attr, action, data, target) {
|
|
29025
29173
|
if (_.isObject(attr)) {
|
|
29026
29174
|
action = attr.action;
|
|
29027
29175
|
data = attr.data;
|
|
29028
29176
|
attr = attr.attr;
|
|
29177
|
+
target = attr.target;
|
|
29029
29178
|
}
|
|
29030
29179
|
if (!attrActionEnum[attr]) {
|
|
29031
29180
|
var validAttrs = _.keys(attrActionEnum).join(', ');
|
|
@@ -29035,11 +29184,16 @@ function UrlAttrTransform(attr, action, data) {
|
|
|
29035
29184
|
var validActions = attrActionEnum[attr].join(', ');
|
|
29036
29185
|
throw new Error('Invalid transform action: "' + action + '" for attribute "' + attr + '". Valid actions for "' + attr + '" are: ' + validActions + '. Example: {attr: "' + attr + '", action: "' + attrActionEnum[attr][0] + '", data: ...}');
|
|
29037
29186
|
}
|
|
29187
|
+
// validate 'target'
|
|
29188
|
+
if (TARGETS.indexOf(target) < 0) {
|
|
29189
|
+
target = DEFAULT_TARGET;
|
|
29190
|
+
}
|
|
29038
29191
|
this.attr = attr;
|
|
29039
29192
|
this.action = action;
|
|
29040
29193
|
this.data = data;
|
|
29194
|
+
this.target = target || DEFAULT_TARGET;
|
|
29041
29195
|
}
|
|
29042
|
-
|
|
29196
|
+
UrlTransform.prototype.applyTo = function (url) {
|
|
29043
29197
|
var actionImpls = {
|
|
29044
29198
|
AllowOnlyKeys(url, attr, data) {
|
|
29045
29199
|
if (_.isFunction(data)) {
|
|
@@ -29112,26 +29266,26 @@ UrlAttrTransform.prototype.applyToURL = function (url) {
|
|
|
29112
29266
|
};
|
|
29113
29267
|
return actionImpls[this.action](url, this.attr, this.data);
|
|
29114
29268
|
};
|
|
29115
|
-
|
|
29269
|
+
UrlTransform.prototype.toString = function () {
|
|
29116
29270
|
return this.attr + ' - ' + this.action + ' - ' + JSON.stringify(this.data);
|
|
29117
29271
|
};
|
|
29118
29272
|
// Static method, not on the instance
|
|
29119
|
-
|
|
29120
|
-
if (obj instanceof
|
|
29273
|
+
UrlTransform.fromJSON = function (obj) {
|
|
29274
|
+
if (obj instanceof UrlTransform) {
|
|
29121
29275
|
return obj;
|
|
29122
29276
|
}
|
|
29123
29277
|
// Validate input is an object
|
|
29124
29278
|
if (!_.isObject(obj)) {
|
|
29125
|
-
throw new Error('
|
|
29279
|
+
throw new Error('UrlTransform.fromJSON expects an object. Received: ' + typeof obj + '. Example: {attr: "search", action: "AddTo", data: {key: "value"}}');
|
|
29126
29280
|
}
|
|
29127
29281
|
// Validate required properties
|
|
29128
29282
|
if (!obj.attr) {
|
|
29129
29283
|
var allValidAttrs = _.keys(attrActionEnum).join(', ');
|
|
29130
|
-
throw new Error('
|
|
29284
|
+
throw new Error('UrlTransform is missing required "attr" property. Valid attributes are: ' + allValidAttrs + '. Example: {attr: "search", action: "AddTo", data: {key: "value"}}');
|
|
29131
29285
|
}
|
|
29132
29286
|
if (!obj.action) {
|
|
29133
29287
|
var attrValidActions = attrActionEnum[obj.attr] ? attrActionEnum[obj.attr].join(', ') : 'AllowOnlyKeys, ExcludeKeys, AddTo, Replace, Clear';
|
|
29134
|
-
throw new Error('
|
|
29288
|
+
throw new Error('UrlTransform is missing required "action" property. Valid actions depend on the attribute. For "' + obj.attr + '" attribute, valid actions are: ' + attrValidActions + '. Example: {attr: "' + obj.attr + '", action: "AddTo", data: {key: "value"}}');
|
|
29135
29289
|
}
|
|
29136
29290
|
// Validate attribute and action combination
|
|
29137
29291
|
if (!attrActionEnum[obj.attr]) {
|
|
@@ -29170,7 +29324,7 @@ UrlAttrTransform.fromJSON = function (obj) {
|
|
|
29170
29324
|
}
|
|
29171
29325
|
}
|
|
29172
29326
|
try {
|
|
29173
|
-
return new
|
|
29327
|
+
return new UrlTransform(obj.attr, obj.action, obj.data, obj.target);
|
|
29174
29328
|
}
|
|
29175
29329
|
catch (error) {
|
|
29176
29330
|
// If it's already a detailed error from our validation, re-throw it
|
|
@@ -29179,7 +29333,7 @@ UrlAttrTransform.fromJSON = function (obj) {
|
|
|
29179
29333
|
throw error;
|
|
29180
29334
|
}
|
|
29181
29335
|
// Otherwise, wrap the original error with context
|
|
29182
|
-
throw new Error('Failed to create
|
|
29336
|
+
throw new Error('Failed to create UrlTransform: ' + error.message + '. Transform object: ' + JSON.stringify(obj));
|
|
29183
29337
|
}
|
|
29184
29338
|
};
|
|
29185
29339
|
|
|
@@ -29189,13 +29343,13 @@ function isURL(u) {
|
|
|
29189
29343
|
var LocationModule = (function (global) {
|
|
29190
29344
|
var createElectronTranforms = function (appname, resourcesPath, directory, userHome) {
|
|
29191
29345
|
return [
|
|
29192
|
-
new
|
|
29346
|
+
new UrlTransform('pathname', 'Replace', function (path) {
|
|
29193
29347
|
var newPath = path.replace(resourcesPath, appname);
|
|
29194
29348
|
newPath = newPath.replace(directory, appname);
|
|
29195
29349
|
newPath = newPath.replace(userHome, '');
|
|
29196
29350
|
return newPath;
|
|
29197
29351
|
}),
|
|
29198
|
-
new
|
|
29352
|
+
new UrlTransform('href', 'ForceSecure')
|
|
29199
29353
|
];
|
|
29200
29354
|
};
|
|
29201
29355
|
var DEFAULT_SRC_FN = function () {
|
|
@@ -29234,17 +29388,23 @@ var LocationModule = (function (global) {
|
|
|
29234
29388
|
},
|
|
29235
29389
|
addTransforms(context, transforms) {
|
|
29236
29390
|
_.each(transforms, function (f) {
|
|
29237
|
-
|
|
29391
|
+
const t = UrlTransform.fromJSON(f);
|
|
29392
|
+
if (t.target === 'location' || t.target === 'both') {
|
|
29393
|
+
context.commit('addTransform', t);
|
|
29394
|
+
}
|
|
29395
|
+
if (t.target === 'attribute' || t.target === 'both') {
|
|
29396
|
+
store.dispatch('nodeAttr/addAttrTransform', t);
|
|
29397
|
+
}
|
|
29238
29398
|
});
|
|
29239
29399
|
},
|
|
29240
29400
|
addInternalTransforms(context, transforms) {
|
|
29241
29401
|
_.each(transforms, function (f) {
|
|
29242
|
-
context.commit('addInternalTransform',
|
|
29402
|
+
context.commit('addInternalTransform', UrlTransform.fromJSON(f));
|
|
29243
29403
|
});
|
|
29244
29404
|
},
|
|
29245
29405
|
removeInternalTransforms(context, transforms) {
|
|
29246
29406
|
_.each(transforms, function (f) {
|
|
29247
|
-
context.commit('removeInternalTransform',
|
|
29407
|
+
context.commit('removeInternalTransform', UrlTransform.fromJSON(f));
|
|
29248
29408
|
});
|
|
29249
29409
|
},
|
|
29250
29410
|
startPolling(context) {
|
|
@@ -29272,6 +29432,7 @@ var LocationModule = (function (global) {
|
|
|
29272
29432
|
},
|
|
29273
29433
|
clearTransforms(state) {
|
|
29274
29434
|
state.transforms = [];
|
|
29435
|
+
store.commit('nodeAttr/clearURLTransforms');
|
|
29275
29436
|
},
|
|
29276
29437
|
clearInternalTransforms(state) {
|
|
29277
29438
|
state.internalTransforms = [];
|
|
@@ -29327,7 +29488,7 @@ var LocationModule = (function (global) {
|
|
|
29327
29488
|
};
|
|
29328
29489
|
var transformUrl = function (transforms, url) {
|
|
29329
29490
|
return _.reduce(transforms, function (tUrl, f) {
|
|
29330
|
-
return f.
|
|
29491
|
+
return f.applyTo(tUrl);
|
|
29331
29492
|
}, url);
|
|
29332
29493
|
};
|
|
29333
29494
|
var urlGetter = function (state) {
|
|
@@ -32544,10 +32705,12 @@ var GuideUpdateModule = (function () {
|
|
|
32544
32705
|
state.scheduledUpdate = scheduledUpdate;
|
|
32545
32706
|
},
|
|
32546
32707
|
startUpdate(state, time) {
|
|
32708
|
+
PerformanceMonitor$1.startTimer('guide-loop');
|
|
32547
32709
|
state.needsUpdate = false;
|
|
32548
32710
|
state.updateId = time;
|
|
32549
32711
|
},
|
|
32550
32712
|
completeUpdate(state, time) {
|
|
32713
|
+
PerformanceMonitor$1.stopTimer('guide-loop');
|
|
32551
32714
|
state.updateId = null;
|
|
32552
32715
|
state.updateCompleteTime = time;
|
|
32553
32716
|
}
|
|
@@ -32656,75 +32819,6 @@ var HealthCheckModule = (function () {
|
|
|
32656
32819
|
};
|
|
32657
32820
|
})();
|
|
32658
32821
|
|
|
32659
|
-
var MonitoringModule = (function () {
|
|
32660
|
-
var state = {
|
|
32661
|
-
lastFlush: getNow(),
|
|
32662
|
-
flushInterval: 5 * 60 * 1000,
|
|
32663
|
-
counters: {
|
|
32664
|
-
ptmGifFailures: 0,
|
|
32665
|
-
guideGifFailures: 0
|
|
32666
|
-
},
|
|
32667
|
-
timers: {}
|
|
32668
|
-
};
|
|
32669
|
-
var actions = {
|
|
32670
|
-
flush(context) {
|
|
32671
|
-
_.each(context.state.counters, function (value, counterName) {
|
|
32672
|
-
context.commit('resetCounter', counterName);
|
|
32673
|
-
});
|
|
32674
|
-
_.each(context.state.timers, function (value, timerName) {
|
|
32675
|
-
context.commit('resetTimer', timerName);
|
|
32676
|
-
});
|
|
32677
|
-
context.commit('setLastFlush', context.getters.now());
|
|
32678
|
-
}
|
|
32679
|
-
};
|
|
32680
|
-
var mutations = {
|
|
32681
|
-
setLastFlush(state, lastFlush) {
|
|
32682
|
-
state.lastFlush = lastFlush;
|
|
32683
|
-
},
|
|
32684
|
-
incrementCounter(state, counterName) {
|
|
32685
|
-
if (state.counters[counterName] === undefined)
|
|
32686
|
-
return;
|
|
32687
|
-
state.counters[counterName]++;
|
|
32688
|
-
},
|
|
32689
|
-
resetCounter(state, counterName) {
|
|
32690
|
-
if (state.counters[counterName] === undefined)
|
|
32691
|
-
return;
|
|
32692
|
-
state.counters[counterName] = 0;
|
|
32693
|
-
},
|
|
32694
|
-
setTimer(state, { name, time } = {}) {
|
|
32695
|
-
if (!name || time == null)
|
|
32696
|
-
return;
|
|
32697
|
-
state.timers[name] = time;
|
|
32698
|
-
},
|
|
32699
|
-
resetTimer(state, timerName) {
|
|
32700
|
-
delete state.timers[timerName];
|
|
32701
|
-
}
|
|
32702
|
-
};
|
|
32703
|
-
var getters = {
|
|
32704
|
-
shouldFlush(state, getters) {
|
|
32705
|
-
return (getters.now() - state.lastFlush) >= state.flushInterval;
|
|
32706
|
-
},
|
|
32707
|
-
payload(state) {
|
|
32708
|
-
var counters = _.reduce(state.counters, function (obj, value, key) {
|
|
32709
|
-
if (value > 0) {
|
|
32710
|
-
obj[key] = value;
|
|
32711
|
-
}
|
|
32712
|
-
return obj;
|
|
32713
|
-
}, {});
|
|
32714
|
-
return _.extend({}, counters, state.timers);
|
|
32715
|
-
},
|
|
32716
|
-
now() {
|
|
32717
|
-
return getNow();
|
|
32718
|
-
}
|
|
32719
|
-
};
|
|
32720
|
-
return {
|
|
32721
|
-
state,
|
|
32722
|
-
actions,
|
|
32723
|
-
mutations,
|
|
32724
|
-
getters
|
|
32725
|
-
};
|
|
32726
|
-
})();
|
|
32727
|
-
|
|
32728
32822
|
var MetadataModule = (function () {
|
|
32729
32823
|
var state = {
|
|
32730
32824
|
visitor: {},
|
|
@@ -32913,7 +33007,6 @@ const DebuggerModule = (() => {
|
|
|
32913
33007
|
context.commit('setTabId', EventTracer.getTabId());
|
|
32914
33008
|
context.commit('setInstallType', getInstallType());
|
|
32915
33009
|
const isTop = isLeader() && window.top === window; // only a leader frame that is a top window can launch debugger
|
|
32916
|
-
state.isTop !== isTop;
|
|
32917
33010
|
context.commit('setIsTop', isTop);
|
|
32918
33011
|
context.commit('isLeader', isLeader());
|
|
32919
33012
|
if (isTop) {
|
|
@@ -32964,6 +33057,8 @@ const DebuggerModule = (() => {
|
|
|
32964
33057
|
context.commit('enableEventLogging', enabled);
|
|
32965
33058
|
},
|
|
32966
33059
|
eventCaptured: (context, data) => {
|
|
33060
|
+
if (pendo$1.designerEnabled || isInPreviewMode() || isInDesignerPreviewMode())
|
|
33061
|
+
return;
|
|
32967
33062
|
if (!context.state.isTop) {
|
|
32968
33063
|
crossFrameChannel.postMessage({
|
|
32969
33064
|
action: 'debugger/receiveEventCaptured',
|
|
@@ -33202,6 +33297,68 @@ const DebuggerModule = (() => {
|
|
|
33202
33297
|
};
|
|
33203
33298
|
})();
|
|
33204
33299
|
|
|
33300
|
+
const NodeAttrModule = (function (global) {
|
|
33301
|
+
const state = {
|
|
33302
|
+
transforms: []
|
|
33303
|
+
};
|
|
33304
|
+
const actions = {
|
|
33305
|
+
addAttrTransform(context, urlTransform) {
|
|
33306
|
+
context.commit('addTransform', urlTransform);
|
|
33307
|
+
}
|
|
33308
|
+
};
|
|
33309
|
+
const mutations = {
|
|
33310
|
+
addTransform(state, transform) {
|
|
33311
|
+
state.transforms.push(transform);
|
|
33312
|
+
},
|
|
33313
|
+
clearURLTransforms(state) {
|
|
33314
|
+
// XXX if ever support non url transforms for attributes then we'll need to check the Transform type
|
|
33315
|
+
// or determine some other way how to purge only URL transforms as Location API provides a way for these to be
|
|
33316
|
+
// cleared via the API.
|
|
33317
|
+
state.transforms = [];
|
|
33318
|
+
}
|
|
33319
|
+
};
|
|
33320
|
+
const applyTransforms = (transforms, url) => {
|
|
33321
|
+
return _.reduce(transforms, function (tUrl, f) {
|
|
33322
|
+
return f.applyTo(tUrl);
|
|
33323
|
+
}, url);
|
|
33324
|
+
};
|
|
33325
|
+
const resolveAttrValueAsURL = (attrValue) => {
|
|
33326
|
+
// let's let the browser do this work for us...
|
|
33327
|
+
const a = document.createElement('a'); // this handles relative urls nicely
|
|
33328
|
+
a.href = attrValue;
|
|
33329
|
+
return new URL(a.href);
|
|
33330
|
+
};
|
|
33331
|
+
const getters = {
|
|
33332
|
+
getAttribute(state) {
|
|
33333
|
+
return function (element, attrName) {
|
|
33334
|
+
let attrValue = element.getAttribute ? element.getAttribute(attrName) : element[attrName];
|
|
33335
|
+
if (_.size(state.transforms) < 1) {
|
|
33336
|
+
return attrValue;
|
|
33337
|
+
}
|
|
33338
|
+
try {
|
|
33339
|
+
let url = resolveAttrValueAsURL(attrValue);
|
|
33340
|
+
url = _.reduce([
|
|
33341
|
+
_.partial(applyTransforms, state.transforms)
|
|
33342
|
+
], (url, fn) => {
|
|
33343
|
+
return fn(url);
|
|
33344
|
+
}, url);
|
|
33345
|
+
return url.href;
|
|
33346
|
+
}
|
|
33347
|
+
catch (e) {
|
|
33348
|
+
log.critical(e);
|
|
33349
|
+
return attrValue;
|
|
33350
|
+
}
|
|
33351
|
+
};
|
|
33352
|
+
}
|
|
33353
|
+
};
|
|
33354
|
+
return {
|
|
33355
|
+
state,
|
|
33356
|
+
actions,
|
|
33357
|
+
mutations,
|
|
33358
|
+
getters
|
|
33359
|
+
};
|
|
33360
|
+
})();
|
|
33361
|
+
|
|
33205
33362
|
function registerModules(store) {
|
|
33206
33363
|
store.registerModule('debugger', DebuggerModule);
|
|
33207
33364
|
store.registerModule('errorLog', ErrorLogModule);
|
|
@@ -33210,9 +33367,9 @@ function registerModules(store) {
|
|
|
33210
33367
|
store.registerModule('guideState', GuideStateModule);
|
|
33211
33368
|
store.registerModule('healthCheck', HealthCheckModule);
|
|
33212
33369
|
store.registerModule('location', LocationModule);
|
|
33213
|
-
store.registerModule('monitoring', MonitoringModule);
|
|
33214
33370
|
store.registerModule('metadata', MetadataModule);
|
|
33215
33371
|
store.registerModule('preview', PreviewModule);
|
|
33372
|
+
store.registerModule('nodeAttr', NodeAttrModule);
|
|
33216
33373
|
}
|
|
33217
33374
|
|
|
33218
33375
|
const IFrameMonitor = (function () {
|
|
@@ -36255,7 +36412,7 @@ const EventProperties = (function () {
|
|
|
36255
36412
|
return [];
|
|
36256
36413
|
}
|
|
36257
36414
|
return [
|
|
36258
|
-
new
|
|
36415
|
+
new UrlTransform('search', 'AddTo', function () { return collectPageEventProperties(); })
|
|
36259
36416
|
];
|
|
36260
36417
|
}
|
|
36261
36418
|
function createPageEventProperties() {
|
|
@@ -47297,6 +47454,7 @@ class SessionRecorder {
|
|
|
47297
47454
|
this.sendQueue = new SendQueue(bind(this.transport.send, this.transport));
|
|
47298
47455
|
this.sendQueue.onTimeout = bind(this.sendFailure, this, 'SEND_TIMEOUT');
|
|
47299
47456
|
this.isNewSession = false;
|
|
47457
|
+
this.isCheckingVisitorEligibility = false;
|
|
47300
47458
|
this.addConfigOptions();
|
|
47301
47459
|
this.config = configReader.get(RECORDING_CONFIG);
|
|
47302
47460
|
this.onRecordingStart = this.pendo._.isFunction(configReader.get(RECORDING_CONFIG_ON_RECORDING_START))
|
|
@@ -47399,19 +47557,32 @@ class SessionRecorder {
|
|
|
47399
47557
|
clearTimeout(this._changeIdentityTimer);
|
|
47400
47558
|
this.visitorId = options.visitor.id;
|
|
47401
47559
|
this.accountId = options.account.id;
|
|
47402
|
-
return this.
|
|
47403
|
-
if ((!visitorConfig || !visitorConfig.enable) && this.isRecording()) {
|
|
47404
|
-
this.stop();
|
|
47405
|
-
}
|
|
47406
|
-
else if (visitorConfig && visitorConfig.enable && !this.isRecording()) {
|
|
47407
|
-
this._startRecordingForVisitor(visitorConfig);
|
|
47408
|
-
}
|
|
47409
|
-
}).catch((e) => {
|
|
47410
|
-
this.api.log.critical('Failed to re-fetch recording config', { error: e });
|
|
47411
|
-
this.logStopReason('VISITOR_CONFIG_ERROR');
|
|
47412
|
-
});
|
|
47560
|
+
return this.checkVisitorEligibility();
|
|
47413
47561
|
}
|
|
47414
47562
|
}
|
|
47563
|
+
checkVisitorEligibility(continuationCallback) {
|
|
47564
|
+
if (!this.isRecording() && this.pendo._.isNull(this.visitorId) && this.pendo._.isNull(this.accountId))
|
|
47565
|
+
return;
|
|
47566
|
+
this.isCheckingVisitorEligibility = true;
|
|
47567
|
+
return this.fetchVisitorConfig().then(visitorConfig => {
|
|
47568
|
+
if ((!visitorConfig || !visitorConfig.enable) && this.isRecording()) {
|
|
47569
|
+
this.stop();
|
|
47570
|
+
}
|
|
47571
|
+
if (visitorConfig && visitorConfig.enable && this.isRecording()) {
|
|
47572
|
+
if (continuationCallback) {
|
|
47573
|
+
continuationCallback.call(this);
|
|
47574
|
+
}
|
|
47575
|
+
}
|
|
47576
|
+
if (visitorConfig && visitorConfig.enable && !this.isRecording()) {
|
|
47577
|
+
this._startRecordingForVisitor(visitorConfig);
|
|
47578
|
+
}
|
|
47579
|
+
}).catch((e) => {
|
|
47580
|
+
this.api.log.critical('Failed to re-fetch recording config', { error: e });
|
|
47581
|
+
this.logStopReason('VISITOR_CONFIG_ERROR');
|
|
47582
|
+
}).finally(() => {
|
|
47583
|
+
this.isCheckingVisitorEligibility = false;
|
|
47584
|
+
});
|
|
47585
|
+
}
|
|
47415
47586
|
snapshot() {
|
|
47416
47587
|
if (!this.isRecording())
|
|
47417
47588
|
return;
|
|
@@ -47673,13 +47844,24 @@ class SessionRecorder {
|
|
|
47673
47844
|
if ((!prevLastEmitTime && isMeta)) {
|
|
47674
47845
|
skipUserInteractionCheck = true;
|
|
47675
47846
|
}
|
|
47676
|
-
|
|
47847
|
+
// Ensures events emitted while the visitor eligibility check is in flight are compared against events emitted
|
|
47848
|
+
// before the visitor eligibility check occurred. This means these events which fall outside of the inactivity
|
|
47849
|
+
// duration will not be placed in the buffer and captured. This is ok since they occurred outside of the
|
|
47850
|
+
// inactivity period and before the next snapshot.
|
|
47851
|
+
if (!this.isCheckingVisitorEligibility) {
|
|
47852
|
+
this.storeLastUserInteractionEventInformation(event, this.visitorId, this.accountId, skipUserInteractionCheck);
|
|
47853
|
+
}
|
|
47677
47854
|
const inactivityDuration = this.pendo._.get(this.visitorConfig, 'inactivityDuration', THIRTY_MINUTES);
|
|
47678
47855
|
if (prevLastEmitTime && event.timestamp - prevLastEmitTime > inactivityDuration && !isSnapshot && !isMeta) {
|
|
47679
|
-
this.
|
|
47680
|
-
|
|
47681
|
-
|
|
47682
|
-
|
|
47856
|
+
if (!this.isCheckingVisitorEligibility) {
|
|
47857
|
+
const continuationCallback = function () {
|
|
47858
|
+
this.send();
|
|
47859
|
+
this.clearSessionInfo();
|
|
47860
|
+
this.snapshot();
|
|
47861
|
+
};
|
|
47862
|
+
this.checkVisitorEligibility(continuationCallback);
|
|
47863
|
+
}
|
|
47864
|
+
return;
|
|
47683
47865
|
}
|
|
47684
47866
|
/*
|
|
47685
47867
|
* META events and Snapshots are special and need to be packaged together. This is made possible by
|
|
@@ -47714,8 +47896,16 @@ class SessionRecorder {
|
|
|
47714
47896
|
const exceedsEventFreq = this.eventsSinceLastKeyFrame >= this.pendo._.get(this.visitorConfig, 'keyframeEventFrequency', 4548); // Defaults determined by BE originally, shouldn't really ever be used
|
|
47715
47897
|
const exceedsRecordingSizeLimit = this.currentRecordingSize >= this.pendo._.get(this.visitorConfig, 'recordingSizeLimit', ONE_HUNDRED_MB_IN_BYTES);
|
|
47716
47898
|
if (exceeds24Hours || (exceedsTimeFreq && exceedsEventFreq) || exceedsRecordingSizeLimit) {
|
|
47717
|
-
|
|
47718
|
-
|
|
47899
|
+
const continuationCallback = function () {
|
|
47900
|
+
this.currentRecordingSize = 0;
|
|
47901
|
+
this.snapshot();
|
|
47902
|
+
};
|
|
47903
|
+
if (exceeds24Hours && !this.isCheckingVisitorEligibility) {
|
|
47904
|
+
this.checkVisitorEligibility(continuationCallback);
|
|
47905
|
+
}
|
|
47906
|
+
else {
|
|
47907
|
+
continuationCallback.call(this);
|
|
47908
|
+
}
|
|
47719
47909
|
}
|
|
47720
47910
|
}
|
|
47721
47911
|
}
|
|
@@ -48954,17 +49144,14 @@ class ConsoleCaptureBuffer {
|
|
|
48954
49144
|
constructor(pendo, pluginAPI) {
|
|
48955
49145
|
this.pendo = pendo;
|
|
48956
49146
|
this.pluginAPI = pluginAPI;
|
|
48957
|
-
this.
|
|
48958
|
-
this.warnEvents = [];
|
|
48959
|
-
this.errorEvents = [];
|
|
49147
|
+
this.events = [];
|
|
48960
49148
|
this.lastEvent = null;
|
|
48961
|
-
this.devLogEvent = null;
|
|
48962
49149
|
this.tokens = TOKEN_MAX_SIZE;
|
|
48963
49150
|
this.lastRefillTime = this.pluginAPI.util.getNow();
|
|
48964
49151
|
this.nextRefillTime = this.lastRefillTime + TOKEN_REFRESH_INTERVAL;
|
|
48965
49152
|
}
|
|
48966
49153
|
isEmpty() {
|
|
48967
|
-
return this.
|
|
49154
|
+
return this.events.length === 0;
|
|
48968
49155
|
}
|
|
48969
49156
|
refillTokens() {
|
|
48970
49157
|
const now = this.pluginAPI.util.getNow();
|
|
@@ -48978,10 +49165,8 @@ class ConsoleCaptureBuffer {
|
|
|
48978
49165
|
}
|
|
48979
49166
|
}
|
|
48980
49167
|
clear() {
|
|
49168
|
+
this.events = [];
|
|
48981
49169
|
this.lastEvent = null;
|
|
48982
|
-
this.infoEvents.length = 0;
|
|
48983
|
-
this.warnEvents.length = 0;
|
|
48984
|
-
this.errorEvents.length = 0;
|
|
48985
49170
|
}
|
|
48986
49171
|
push(event) {
|
|
48987
49172
|
const { devLogLevel } = event;
|
|
@@ -48991,50 +49176,16 @@ class ConsoleCaptureBuffer {
|
|
|
48991
49176
|
if (this.tokens === 0)
|
|
48992
49177
|
return false;
|
|
48993
49178
|
this.lastEvent = event;
|
|
48994
|
-
this.
|
|
49179
|
+
this.events.push(event);
|
|
48995
49180
|
this.tokens = Math.max(this.tokens - 1, 0);
|
|
48996
49181
|
return true;
|
|
48997
49182
|
}
|
|
48998
|
-
|
|
48999
|
-
switch (event.devLogLevel) {
|
|
49000
|
-
case 'info':
|
|
49001
|
-
this.infoEvents.push(event);
|
|
49002
|
-
break;
|
|
49003
|
-
case 'warn':
|
|
49004
|
-
this.warnEvents.push(event);
|
|
49005
|
-
break;
|
|
49006
|
-
case 'error':
|
|
49007
|
-
this.errorEvents.push(event);
|
|
49008
|
-
break;
|
|
49009
|
-
}
|
|
49010
|
-
}
|
|
49011
|
-
createDevLogEventWithPayload({ events, level }) {
|
|
49012
|
-
if (events.length === 0)
|
|
49013
|
-
return;
|
|
49014
|
-
const totalCount = this.pendo._.reduce(events, (sum, event) => sum + (event.devLogCount || 1), 0);
|
|
49015
|
-
return Object.assign(Object.assign({}, this.devLogEvent), { devLogLevel: level, devLogCount: totalCount, devLogPayload: this.pendo.compress(events) });
|
|
49016
|
-
}
|
|
49017
|
-
generateJZB() {
|
|
49018
|
-
const payload = [];
|
|
49019
|
-
this.pendo._.each(DEV_LOG_LEVELS, level => {
|
|
49020
|
-
const events = this[`${level}Events`];
|
|
49021
|
-
if (events.length === 0)
|
|
49022
|
-
return;
|
|
49023
|
-
const devLogEventWithPayload = this.createDevLogEventWithPayload({
|
|
49024
|
-
events,
|
|
49025
|
-
level
|
|
49026
|
-
});
|
|
49027
|
-
payload.push(devLogEventWithPayload);
|
|
49028
|
-
});
|
|
49029
|
-
this.devLogEvent = null;
|
|
49030
|
-
return this.pendo.compress(payload);
|
|
49031
|
-
}
|
|
49032
|
-
pack(url) {
|
|
49183
|
+
pack() {
|
|
49033
49184
|
if (this.isEmpty())
|
|
49034
|
-
return
|
|
49035
|
-
const jzb = this.
|
|
49185
|
+
return;
|
|
49186
|
+
const jzb = this.pendo.compress(this.events);
|
|
49036
49187
|
this.clear();
|
|
49037
|
-
return
|
|
49188
|
+
return jzb;
|
|
49038
49189
|
}
|
|
49039
49190
|
}
|
|
49040
49191
|
|
|
@@ -55818,12 +55969,11 @@ function ConsoleCapture() {
|
|
|
55818
55969
|
initialize,
|
|
55819
55970
|
teardown,
|
|
55820
55971
|
addIntercepts,
|
|
55821
|
-
|
|
55972
|
+
createConsoleEvent,
|
|
55822
55973
|
captureStackTrace,
|
|
55823
55974
|
send,
|
|
55824
55975
|
onAppHidden,
|
|
55825
55976
|
onAppUnloaded,
|
|
55826
|
-
onEventCaptured,
|
|
55827
55977
|
onPtmPaused,
|
|
55828
55978
|
onPtmUnpaused,
|
|
55829
55979
|
get buffer() {
|
|
@@ -55857,7 +56007,6 @@ function ConsoleCapture() {
|
|
|
55857
56007
|
pluginAPI.Events.ready.on(addIntercepts);
|
|
55858
56008
|
pluginAPI.Events.appUnloaded.on(onAppUnloaded);
|
|
55859
56009
|
pluginAPI.Events.appHidden.on(onAppHidden);
|
|
55860
|
-
pluginAPI.Events.eventCaptured.on(onEventCaptured);
|
|
55861
56010
|
pluginAPI.Events['ptm:paused'].on(onPtmPaused);
|
|
55862
56011
|
pluginAPI.Events['ptm:unpaused'].on(onPtmUnpaused);
|
|
55863
56012
|
pluginAPI.log.info('Console logs are being captured');
|
|
@@ -55868,36 +56017,19 @@ function ConsoleCapture() {
|
|
|
55868
56017
|
function onAppUnloaded() {
|
|
55869
56018
|
send({ unload: true });
|
|
55870
56019
|
}
|
|
55871
|
-
/**
|
|
55872
|
-
* Handles eventCaptured events to monitor recordingId changes and/or link devLog events with recordingId
|
|
55873
|
-
*
|
|
55874
|
-
* @param {object} event - eventCaptured event
|
|
55875
|
-
*/
|
|
55876
|
-
function onEventCaptured(event) {
|
|
55877
|
-
if (!event || !event.data || !event.data.length || !buffer.devLogEvent)
|
|
55878
|
-
return;
|
|
55879
|
-
const capturedEvent = event.data[0];
|
|
55880
|
-
const { type, recordingId, recordingSessionId } = capturedEvent;
|
|
55881
|
-
if (type === DEV_LOG_TYPE || type === 'identify' || !recordingId || !recordingSessionId)
|
|
55882
|
-
return;
|
|
55883
|
-
const { recordingId: devLogRecordingId } = buffer.devLogEvent;
|
|
55884
|
-
// if recordingId has changed, send current buffer immediately to separate recording sessions
|
|
55885
|
-
if (devLogRecordingId && recordingId !== devLogRecordingId) {
|
|
55886
|
-
send();
|
|
55887
|
-
return;
|
|
55888
|
-
}
|
|
55889
|
-
}
|
|
55890
56020
|
function onPtmPaused() {
|
|
55891
56021
|
isPtmPaused = true;
|
|
55892
56022
|
}
|
|
55893
56023
|
function onPtmUnpaused() {
|
|
55894
56024
|
isPtmPaused = false;
|
|
55895
|
-
if (!buffer.
|
|
55896
|
-
buffer.
|
|
56025
|
+
if (!buffer.isEmpty()) {
|
|
56026
|
+
for (const event of buffer.events) {
|
|
56027
|
+
pluginAPI.Events.eventCaptured.trigger(event);
|
|
56028
|
+
}
|
|
56029
|
+
send();
|
|
55897
56030
|
}
|
|
55898
|
-
pluginAPI.Events.eventCaptured.trigger(buffer.devLogEvent);
|
|
55899
56031
|
}
|
|
55900
|
-
function
|
|
56032
|
+
function createDevLogEnvelope() {
|
|
55901
56033
|
return {
|
|
55902
56034
|
visitorId: globalPendo.get_visitor_id(),
|
|
55903
56035
|
accountId: globalPendo.get_account_id(),
|
|
@@ -55916,14 +56048,14 @@ function ConsoleCapture() {
|
|
|
55916
56048
|
// slice 1 to omit originalFn
|
|
55917
56049
|
const args = _.toArray(arguments).slice(1);
|
|
55918
56050
|
originalFn.apply(console, args);
|
|
55919
|
-
|
|
56051
|
+
createConsoleEvent(args, methodName);
|
|
55920
56052
|
});
|
|
55921
56053
|
console[methodName]._pendoUnwrap = function () {
|
|
55922
56054
|
console[methodName] = originalMethod;
|
|
55923
56055
|
};
|
|
55924
56056
|
});
|
|
55925
56057
|
}
|
|
55926
|
-
function
|
|
56058
|
+
function createConsoleEvent(args, methodName) {
|
|
55927
56059
|
if (!args || args.length === 0)
|
|
55928
56060
|
return;
|
|
55929
56061
|
// stringify args
|
|
@@ -55951,22 +56083,16 @@ function ConsoleCapture() {
|
|
|
55951
56083
|
buffer.lastEvent.devLogCount++;
|
|
55952
56084
|
return;
|
|
55953
56085
|
}
|
|
55954
|
-
const
|
|
55955
|
-
|
|
55956
|
-
|
|
55957
|
-
devLogTrace: stackTrace,
|
|
55958
|
-
devLogTimestamp: pluginAPI.util.getNow(),
|
|
55959
|
-
devLogCount: 1
|
|
55960
|
-
};
|
|
55961
|
-
const wasAccepted = buffer.push(devLog);
|
|
56086
|
+
const devLogEnvelope = createDevLogEnvelope();
|
|
56087
|
+
const consoleEvent = Object.assign(Object.assign({}, devLogEnvelope), { devLogLevel: methodName === 'log' ? 'info' : methodName, devLogMessage: scrubPII(message), devLogTrace: stackTrace, devLogCount: 1 });
|
|
56088
|
+
const wasAccepted = buffer.push(consoleEvent);
|
|
55962
56089
|
if (wasAccepted) {
|
|
55963
|
-
if (
|
|
55964
|
-
|
|
55965
|
-
pluginAPI.Events.eventCaptured.trigger(buffer.devLogEvent);
|
|
56090
|
+
if (!isPtmPaused) {
|
|
56091
|
+
pluginAPI.Events.eventCaptured.trigger(consoleEvent);
|
|
55966
56092
|
}
|
|
55967
56093
|
updateLastLog(logKey);
|
|
55968
56094
|
}
|
|
55969
|
-
return
|
|
56095
|
+
return consoleEvent;
|
|
55970
56096
|
}
|
|
55971
56097
|
function captureStackTrace(maxStackFrames) {
|
|
55972
56098
|
try {
|
|
@@ -55986,19 +56112,23 @@ function ConsoleCapture() {
|
|
|
55986
56112
|
function send({ unload = false, hidden = false } = {}) {
|
|
55987
56113
|
if (!buffer || buffer.isEmpty())
|
|
55988
56114
|
return;
|
|
56115
|
+
if (!globalPendo.isSendingEvents()) {
|
|
56116
|
+
buffer.clear();
|
|
56117
|
+
return;
|
|
56118
|
+
}
|
|
55989
56119
|
const queryParams = {
|
|
55990
56120
|
v: globalPendo.VERSION,
|
|
55991
56121
|
ct: pluginAPI.util.getNow()
|
|
55992
56122
|
};
|
|
55993
56123
|
const url = pluginAPI.transmit.buildBaseDataUrl('devlog', globalPendo.apiKey, queryParams);
|
|
55994
|
-
const
|
|
55995
|
-
if (!
|
|
56124
|
+
const jzb = buffer.pack();
|
|
56125
|
+
if (!jzb)
|
|
55996
56126
|
return;
|
|
55997
56127
|
if (unload || hidden) {
|
|
55998
|
-
sendQueue.drain(
|
|
56128
|
+
sendQueue.drain([{ url, jzb }], unload);
|
|
55999
56129
|
}
|
|
56000
56130
|
else {
|
|
56001
|
-
sendQueue.push(
|
|
56131
|
+
sendQueue.push({ url, jzb });
|
|
56002
56132
|
}
|
|
56003
56133
|
}
|
|
56004
56134
|
function teardown() {
|
|
@@ -56014,7 +56144,6 @@ function ConsoleCapture() {
|
|
|
56014
56144
|
}
|
|
56015
56145
|
pluginAPI.Events.appHidden.off(onAppHidden);
|
|
56016
56146
|
pluginAPI.Events.appUnloaded.off(onAppUnloaded);
|
|
56017
|
-
pluginAPI.Events.eventCaptured.off(onEventCaptured);
|
|
56018
56147
|
pluginAPI.Events['ptm:paused'].off(onPtmPaused);
|
|
56019
56148
|
pluginAPI.Events['ptm:unpaused'].off(onPtmUnpaused);
|
|
56020
56149
|
_.each(CONSOLE_METHODS, function (methodName) {
|