@pendo/agent 2.313.0 → 2.314.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/dom.esm.js +1 -2
- package/dist/pendo.debugger.min.js +4 -4
- package/dist/pendo.module.js +123 -65
- package/dist/pendo.module.min.js +9 -9
- package/dist/servers.json +7 -7
- package/package.json +1 -1
package/dist/pendo.module.js
CHANGED
|
@@ -3389,7 +3389,6 @@ var ConfigReader = (function () {
|
|
|
3389
3389
|
* @type {number}
|
|
3390
3390
|
*/
|
|
3391
3391
|
addOption('guideSeenTimeoutLength', [PENDO_CONFIG_SRC, SNIPPET_SRC], 10000);
|
|
3392
|
-
// addOption('guideTimeout', [SNIPPET_SRC]); // old, use guides.timeout instead
|
|
3393
3392
|
/**
|
|
3394
3393
|
* If `true`, guides will be verified against their saved content hash before display to ensure validity of
|
|
3395
3394
|
* guide content.
|
|
@@ -3946,8 +3945,8 @@ let SERVER = '';
|
|
|
3946
3945
|
let ASSET_HOST = '';
|
|
3947
3946
|
let ASSET_PATH = '';
|
|
3948
3947
|
let DESIGNER_SERVER = '';
|
|
3949
|
-
let VERSION = '2.
|
|
3950
|
-
let PACKAGE_VERSION = '2.
|
|
3948
|
+
let VERSION = '2.314.0_';
|
|
3949
|
+
let PACKAGE_VERSION = '2.314.0';
|
|
3951
3950
|
let LOADER = 'xhr';
|
|
3952
3951
|
/* eslint-enable web-sdk-eslint-rules/no-gulp-env-references */
|
|
3953
3952
|
/**
|
|
@@ -12275,16 +12274,17 @@ var JWT = (function () {
|
|
|
12275
12274
|
};
|
|
12276
12275
|
})();
|
|
12277
12276
|
|
|
12278
|
-
const
|
|
12279
|
-
const
|
|
12277
|
+
const MAX_RETRY_DELAY_MS = 5 * 60 * 1000; // 5 minutes
|
|
12278
|
+
const ONE_HOUR = 60 * 60 * 1000; // 1 hour
|
|
12279
|
+
const FAILURE_WINDOW_MS = 2 * ONE_HOUR;
|
|
12280
12280
|
class SendQueue {
|
|
12281
|
-
constructor(sendFn
|
|
12281
|
+
constructor(sendFn) {
|
|
12282
12282
|
this.queue = [];
|
|
12283
12283
|
this.unloads = new Set();
|
|
12284
12284
|
this.pending = new Set();
|
|
12285
12285
|
this.failures = new Map();
|
|
12286
|
+
this.firstFailureTime = null;
|
|
12286
12287
|
this.sendFn = sendFn;
|
|
12287
|
-
this.maxFailures = maxFailures;
|
|
12288
12288
|
}
|
|
12289
12289
|
isEmpty() {
|
|
12290
12290
|
return this.queue.length <= 0;
|
|
@@ -12294,6 +12294,7 @@ class SendQueue {
|
|
|
12294
12294
|
this.unloads.clear();
|
|
12295
12295
|
this.pending.clear();
|
|
12296
12296
|
this.failures.clear();
|
|
12297
|
+
this.firstFailureTime = null;
|
|
12297
12298
|
this.stopped = true;
|
|
12298
12299
|
clearTimeout(this.timer);
|
|
12299
12300
|
delete this.timer;
|
|
@@ -12314,12 +12315,16 @@ class SendQueue {
|
|
|
12314
12315
|
incrementFailure(payload) {
|
|
12315
12316
|
const failureCount = (this.failures.get(payload) || 0) + 1;
|
|
12316
12317
|
this.failures.set(payload, failureCount);
|
|
12318
|
+
if (this.firstFailureTime == null) {
|
|
12319
|
+
this.firstFailureTime = new Date().getTime();
|
|
12320
|
+
}
|
|
12317
12321
|
return failureCount;
|
|
12318
12322
|
}
|
|
12319
12323
|
pass(payload, dequeue = true) {
|
|
12320
12324
|
this.unloads.delete(payload);
|
|
12321
12325
|
this.pending.delete(payload);
|
|
12322
|
-
this.failures.
|
|
12326
|
+
this.failures.delete(payload);
|
|
12327
|
+
this.firstFailureTime = null;
|
|
12323
12328
|
const index = this.queue.indexOf(payload);
|
|
12324
12329
|
if (index >= 0) {
|
|
12325
12330
|
this.queue.splice(index, 1);
|
|
@@ -12334,18 +12339,26 @@ class SendQueue {
|
|
|
12334
12339
|
const failureCount = this.incrementFailure(payload);
|
|
12335
12340
|
if (this.stopped || !retry)
|
|
12336
12341
|
return;
|
|
12337
|
-
|
|
12342
|
+
const now = new Date().getTime();
|
|
12343
|
+
const elapsed = now - (this.firstFailureTime || now);
|
|
12344
|
+
if (elapsed >= FAILURE_WINDOW_MS) {
|
|
12338
12345
|
if (this.onTimeout) {
|
|
12339
12346
|
this.onTimeout();
|
|
12340
12347
|
}
|
|
12341
|
-
this.
|
|
12348
|
+
this.firstFailureTime = null;
|
|
12349
|
+
this.retryLater(ONE_HOUR);
|
|
12350
|
+
return;
|
|
12342
12351
|
}
|
|
12343
|
-
this.retryLater(Math.pow(2,
|
|
12352
|
+
this.retryLater(Math.min(Math.pow(2, failureCount - 1) * 1000, MAX_RETRY_DELAY_MS));
|
|
12353
|
+
}
|
|
12354
|
+
retryNow() {
|
|
12355
|
+
clearTimeout(this.timer);
|
|
12356
|
+
delete this.timer;
|
|
12357
|
+
this.next();
|
|
12344
12358
|
}
|
|
12345
12359
|
retryLater(delay) {
|
|
12346
12360
|
this.timer = setTimeout$1(() => {
|
|
12347
|
-
|
|
12348
|
-
this.next();
|
|
12361
|
+
this.retryNow();
|
|
12349
12362
|
}, delay);
|
|
12350
12363
|
}
|
|
12351
12364
|
failed() {
|
|
@@ -12360,7 +12373,7 @@ class SendQueue {
|
|
|
12360
12373
|
}
|
|
12361
12374
|
drain(finalPayloadArray, isUnload = true) {
|
|
12362
12375
|
this.queue.push(...finalPayloadArray);
|
|
12363
|
-
if (this.failed())
|
|
12376
|
+
if (this.failed() && !this.allowDrainWhileFailed)
|
|
12364
12377
|
return Promise$2.reject();
|
|
12365
12378
|
const promises = [];
|
|
12366
12379
|
for (const payload of this.queue) {
|
|
@@ -12379,7 +12392,7 @@ class SendQueue {
|
|
|
12379
12392
|
}
|
|
12380
12393
|
|
|
12381
12394
|
const UNSENT_EVENTS_KEY = 'unsentEvents';
|
|
12382
|
-
const
|
|
12395
|
+
const UNSENT_EVENTS_MAX_AGE = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
12383
12396
|
class LocalStorageEventBuffer {
|
|
12384
12397
|
constructor() {
|
|
12385
12398
|
this.events = {};
|
|
@@ -12421,7 +12434,7 @@ class LocalStorageEventBuffer {
|
|
|
12421
12434
|
}
|
|
12422
12435
|
write(storage) {
|
|
12423
12436
|
if (_.size(this.events) > 0) {
|
|
12424
|
-
storage.write(UNSENT_EVENTS_KEY, JSON.stringify(this.events),
|
|
12437
|
+
storage.write(UNSENT_EVENTS_KEY, JSON.stringify(this.events), UNSENT_EVENTS_MAX_AGE);
|
|
12425
12438
|
}
|
|
12426
12439
|
else {
|
|
12427
12440
|
storage.clear(UNSENT_EVENTS_KEY);
|
|
@@ -12920,6 +12933,7 @@ function addSiloParams(options) {
|
|
|
12920
12933
|
silo.params = _.extend({}, silo.params, options.params);
|
|
12921
12934
|
silo.beacon = options.beacon;
|
|
12922
12935
|
silo.eventLength = silo.JZB.length;
|
|
12936
|
+
silo.ts = silo[0].browser_time || getNow();
|
|
12923
12937
|
var jwtOptions = JWT.get();
|
|
12924
12938
|
if (!_.isEmpty(jwtOptions)) {
|
|
12925
12939
|
silo.auth = jwtOptions;
|
|
@@ -13110,6 +13124,9 @@ function createSendQueue(options, send, guaranteedSend) {
|
|
|
13110
13124
|
const apiKeys = getApiKeysFromOptions(options);
|
|
13111
13125
|
const queues = _.map(apiKeys, (apiKey, i) => {
|
|
13112
13126
|
const queue = new SendQueue(function (request, isUnload, failureCount) {
|
|
13127
|
+
if (getNow() - request.ts > UNSENT_EVENTS_MAX_AGE) {
|
|
13128
|
+
return q.resolve(); // ignore event if it's too old
|
|
13129
|
+
}
|
|
13113
13130
|
if (failureCount) {
|
|
13114
13131
|
request.params = _.extend({}, request.params, {
|
|
13115
13132
|
rt: failureCount
|
|
@@ -13121,7 +13138,10 @@ function createSendQueue(options, send, guaranteedSend) {
|
|
|
13121
13138
|
}
|
|
13122
13139
|
return q.resolve();
|
|
13123
13140
|
}
|
|
13124
|
-
|
|
13141
|
+
if (isUnload && queue.failed()) {
|
|
13142
|
+
return q.reject();
|
|
13143
|
+
}
|
|
13144
|
+
if (isUnload) {
|
|
13125
13145
|
return guaranteedSend(apiKey, request);
|
|
13126
13146
|
}
|
|
13127
13147
|
else {
|
|
@@ -13131,6 +13151,7 @@ function createSendQueue(options, send, guaranteedSend) {
|
|
|
13131
13151
|
queue.onTimeout = function () {
|
|
13132
13152
|
performanceMonitor.count(BEACON_GIF_FAILURES[options.beacon]);
|
|
13133
13153
|
};
|
|
13154
|
+
queue.allowDrainWhileFailed = true;
|
|
13134
13155
|
queue.retryPending = true;
|
|
13135
13156
|
return queue;
|
|
13136
13157
|
});
|
|
@@ -25978,6 +25999,9 @@ var mostRecentGuideRequest;
|
|
|
25978
25999
|
var loadGuideJs = function (apiKey, params) {
|
|
25979
26000
|
var guideRequestId = _.uniqueId();
|
|
25980
26001
|
var deferred = q.defer();
|
|
26002
|
+
if (mostRecentGuideRequest && mostRecentGuideRequest.deferred) {
|
|
26003
|
+
mostRecentGuideRequest.deferred.reject('newRequest'); // make sure that we don't leave open any promises if multiple guide requests are made in quick succession
|
|
26004
|
+
}
|
|
25981
26005
|
mostRecentGuideRequest = {
|
|
25982
26006
|
id: guideRequestId,
|
|
25983
26007
|
deferred
|
|
@@ -26204,8 +26228,7 @@ var loadGuides = function (apiKey, visitorId, page, callback) {
|
|
|
26204
26228
|
resetPendoUI();
|
|
26205
26229
|
var lastGuideStepSeen = pendo$1.lastGuideStepSeen;
|
|
26206
26230
|
if (!lastGuideStepSeen) {
|
|
26207
|
-
|
|
26208
|
-
return;
|
|
26231
|
+
throw new Error('lastGuideStepSeen is not set, check response from guide payload');
|
|
26209
26232
|
}
|
|
26210
26233
|
store.dispatch('guideState/receiveLastGuideStepSeen', lastGuideStepSeen);
|
|
26211
26234
|
lastGuideStepSeen.visitorId = visitorId;
|
|
@@ -26270,6 +26293,12 @@ var loadGuides = function (apiKey, visitorId, page, callback) {
|
|
|
26270
26293
|
}
|
|
26271
26294
|
}
|
|
26272
26295
|
}).catch(function (err) {
|
|
26296
|
+
if (err === 'newRequest') {
|
|
26297
|
+
log.info('Guide load cancelled due to new request');
|
|
26298
|
+
deferred.resolve('Guide load cancelled due to new request');
|
|
26299
|
+
return;
|
|
26300
|
+
}
|
|
26301
|
+
log.info(`Error in loadGuideJs, shutting down guides, err: ${_.get(err, 'message', err || 'Unknown error')}`);
|
|
26273
26302
|
Events.guidesFailed.trigger();
|
|
26274
26303
|
deferred.reject(err);
|
|
26275
26304
|
});
|
|
@@ -38501,7 +38530,6 @@ const FrustrationEvent = (function () {
|
|
|
38501
38530
|
// A guide that show nested inside another element.
|
|
38502
38531
|
// Multiple embedded guides can show at the same time.
|
|
38503
38532
|
const buildGuideBehaviors = function ({ globalPendo, pluginApi }) {
|
|
38504
|
-
const guide = this;
|
|
38505
38533
|
const { _ } = globalPendo;
|
|
38506
38534
|
const { store } = pluginApi;
|
|
38507
38535
|
this.process = function () {
|
|
@@ -38558,12 +38586,6 @@ const buildGuideBehaviors = function ({ globalPendo, pluginApi }) {
|
|
|
38558
38586
|
const nextStep = guide.nextStep(lastSeenStep) || firstStep;
|
|
38559
38587
|
return nextStep.show(reason);
|
|
38560
38588
|
};
|
|
38561
|
-
// when embedded guide is initialized set the forceShowFirstStep property.
|
|
38562
|
-
// This property is deleted after the guide shows because we no longer want to foce show the first step.
|
|
38563
|
-
// The propert is reset on urlChanged events.
|
|
38564
|
-
if (!this.hasOwnProperty('forceShowFirstStep')) {
|
|
38565
|
-
this.forceShowFirstStep = _.get(guide, 'attributes.restartOnReload');
|
|
38566
|
-
}
|
|
38567
38589
|
this.isShownInThisFrame = function () {
|
|
38568
38590
|
const guide = this;
|
|
38569
38591
|
return _.any(guide.steps, function (step) {
|
|
@@ -38620,7 +38642,6 @@ const EmbeddedGuides = (function () {
|
|
|
38620
38642
|
pluginApi.Events.on('deliverablesLoaded', clearEmbeddedGuides);
|
|
38621
38643
|
pluginApi.Events.on('guideLoopStopped', onGuidesStopped);
|
|
38622
38644
|
pluginApi.Events.on('guideListChanged', initializeEmbeddedGuides);
|
|
38623
|
-
pluginApi.Events.on('urlChanged', setForceShowFirstStepFlags);
|
|
38624
38645
|
pluginApi.Events.on('guideAdvanced', hideGuide);
|
|
38625
38646
|
pluginApi.Events.on('metadata', onMetadataChange);
|
|
38626
38647
|
pluginApi.Events.on('identify', onIdentify);
|
|
@@ -38635,7 +38656,6 @@ const EmbeddedGuides = (function () {
|
|
|
38635
38656
|
pluginApi.Events.off('deliverablesLoaded', clearEmbeddedGuides);
|
|
38636
38657
|
pluginApi.Events.off('guideLoopStopped', onGuidesStopped);
|
|
38637
38658
|
pluginApi.Events.off('guideListChanged', initializeEmbeddedGuides);
|
|
38638
|
-
pluginApi.Events.off('urlChanged', setForceShowFirstStepFlags);
|
|
38639
38659
|
pluginApi.Events.off('guideAdvanced', hideGuide);
|
|
38640
38660
|
pluginApi.Events.off('metadata', onMetadataChange);
|
|
38641
38661
|
pluginApi.Events.off('identify', onIdentify);
|
|
@@ -38700,13 +38720,6 @@ const EmbeddedGuides = (function () {
|
|
|
38700
38720
|
function onIdentify() {
|
|
38701
38721
|
setEmbeddedGuideCacheValid(false);
|
|
38702
38722
|
}
|
|
38703
|
-
// This function syncs the forceShowFirstStep with the restartOnReload property on guides
|
|
38704
|
-
// This function is run on the urlChanged event.
|
|
38705
|
-
function setForceShowFirstStepFlags() {
|
|
38706
|
-
_.forEach(embeddedGuides, function (guide) {
|
|
38707
|
-
guide.forceShowFirstStep = !!_.get(guide, 'attributes.restartOnReload');
|
|
38708
|
-
});
|
|
38709
|
-
}
|
|
38710
38723
|
function extractEmbeddedGuides(guide) {
|
|
38711
38724
|
if (isEmbedded(guide)) {
|
|
38712
38725
|
if (!_.some(embeddedGuides, ({ id }) => id === guide.id)) {
|
|
@@ -40339,6 +40352,35 @@ class PromptPlugin {
|
|
|
40339
40352
|
}
|
|
40340
40353
|
var PromptAnalytics = new PromptPlugin();
|
|
40341
40354
|
|
|
40355
|
+
class RestartOnReload {
|
|
40356
|
+
initialize(pendo, { Events }) {
|
|
40357
|
+
this.pendo = pendo;
|
|
40358
|
+
const { _, attachEvent } = pendo;
|
|
40359
|
+
const boundSetForceShowFirstStepFlags = _.bind(this.setForceShowFirstStepFlags, this);
|
|
40360
|
+
this.subscriptions = [
|
|
40361
|
+
attachEvent(Events, 'deliverablesLoaded', boundSetForceShowFirstStepFlags),
|
|
40362
|
+
attachEvent(Events, 'urlChanged', boundSetForceShowFirstStepFlags)
|
|
40363
|
+
];
|
|
40364
|
+
}
|
|
40365
|
+
teardown() {
|
|
40366
|
+
this.pendo._.forEach(this.subscriptions, function (unsubscribe) {
|
|
40367
|
+
unsubscribe();
|
|
40368
|
+
});
|
|
40369
|
+
this.subscriptions.length = 0;
|
|
40370
|
+
}
|
|
40371
|
+
setForceShowFirstStepFlags() {
|
|
40372
|
+
const { pendo } = this;
|
|
40373
|
+
const { _ } = pendo;
|
|
40374
|
+
_.forEach(pendo.guides, function (guide) {
|
|
40375
|
+
const restartOnReload = !!_.get(guide, 'attributes.restartOnReload');
|
|
40376
|
+
if (restartOnReload) {
|
|
40377
|
+
guide.forceShowFirstStep = true;
|
|
40378
|
+
}
|
|
40379
|
+
});
|
|
40380
|
+
}
|
|
40381
|
+
}
|
|
40382
|
+
var RestartOnReload$1 = new RestartOnReload();
|
|
40383
|
+
|
|
40342
40384
|
function registerBuiltInPlugins() {
|
|
40343
40385
|
registerPlugin(IFrameMonitor);
|
|
40344
40386
|
registerPlugin(DOMActivation);
|
|
@@ -40358,6 +40400,7 @@ function registerBuiltInPlugins() {
|
|
|
40358
40400
|
registerPlugin(WebAnalytics$1);
|
|
40359
40401
|
registerPlugin(FormValidation);
|
|
40360
40402
|
registerPlugin(PromptAnalytics);
|
|
40403
|
+
registerPlugin(RestartOnReload$1);
|
|
40361
40404
|
}
|
|
40362
40405
|
|
|
40363
40406
|
/*
|
|
@@ -40536,6 +40579,7 @@ const substitutionRegex = '\\{(?:\\s?)([^.\\s]?visitor|account|parentAccount)\\.
|
|
|
40536
40579
|
const skipStepString = '{skipStep:* *(auto|\\d+)\\/}';
|
|
40537
40580
|
const goToMiddleString = '(?!0)(\\d+)';
|
|
40538
40581
|
const goToString = `({goto-${goToMiddleString}\\/})`;
|
|
40582
|
+
const containerSelector = '[id^="pendo-guide-container"]';
|
|
40539
40583
|
function lookupGuideButtons(domJson, buttons = []) {
|
|
40540
40584
|
if (domJson.type === 'button' && domJson.actions) {
|
|
40541
40585
|
buttons.push(domJson);
|
|
@@ -40573,6 +40617,7 @@ var guideMarkdownUtil = {
|
|
|
40573
40617
|
substitutionRegex,
|
|
40574
40618
|
skipStepString,
|
|
40575
40619
|
goToString,
|
|
40620
|
+
containerSelector,
|
|
40576
40621
|
lookupGuideButtons,
|
|
40577
40622
|
removeMarkdownSyntax
|
|
40578
40623
|
};
|
|
@@ -40626,7 +40671,7 @@ const PollBranching = {
|
|
|
40626
40671
|
attributes: true,
|
|
40627
40672
|
childList: true,
|
|
40628
40673
|
characterData: true,
|
|
40629
|
-
subtree:
|
|
40674
|
+
subtree: true
|
|
40630
40675
|
};
|
|
40631
40676
|
const MutationObserver = getZoneSafeMethod$1(pendo._, 'MutationObserver');
|
|
40632
40677
|
const observer = new MutationObserver(applyBranchingIndicators);
|
|
@@ -40745,13 +40790,13 @@ function branchingGoToStep(event, step, guide, pendo) {
|
|
|
40745
40790
|
if (pollStepIndex < 0)
|
|
40746
40791
|
return;
|
|
40747
40792
|
const destinationObject = {
|
|
40748
|
-
destinationStepId: guide.steps[pollStepIndex].id
|
|
40793
|
+
destinationStepId: guide.steps[pollStepIndex].id,
|
|
40794
|
+
step
|
|
40749
40795
|
};
|
|
40750
40796
|
pendo.goToStep(destinationObject);
|
|
40751
40797
|
event.cancel = true;
|
|
40752
40798
|
}
|
|
40753
40799
|
|
|
40754
|
-
const containerSelector = '[id^="pendo-guide-container"]';
|
|
40755
40800
|
const MetadataSubstitution = {
|
|
40756
40801
|
name: 'MetadataSubstitution',
|
|
40757
40802
|
script(step, guide, pendo) {
|
|
@@ -40775,7 +40820,7 @@ const MetadataSubstitution = {
|
|
|
40775
40820
|
attributes: true,
|
|
40776
40821
|
childList: true,
|
|
40777
40822
|
characterData: true,
|
|
40778
|
-
subtree:
|
|
40823
|
+
subtree: true
|
|
40779
40824
|
};
|
|
40780
40825
|
const MutationObserver = getZoneSafeMethod$1(pendo._, 'MutationObserver');
|
|
40781
40826
|
const observer = new MutationObserver(applySubstitutionIndicators);
|
|
@@ -40784,7 +40829,7 @@ const MetadataSubstitution = {
|
|
|
40784
40829
|
pendo._.each(mutations, function (mutation) {
|
|
40785
40830
|
var _a;
|
|
40786
40831
|
if (mutation.addedNodes.length) {
|
|
40787
|
-
if (document.querySelector(containerSelector)) {
|
|
40832
|
+
if (document.querySelector(guideMarkdownUtil.containerSelector)) {
|
|
40788
40833
|
const placeholderData = findSubstitutableElements(pendo);
|
|
40789
40834
|
const step = (_a = pendo.designerv2.currentlyPreviewedGuide) === null || _a === void 0 ? void 0 : _a.steps[0];
|
|
40790
40835
|
if (!step)
|
|
@@ -40851,9 +40896,9 @@ function substituteMetadataByTarget(data, target, mdValue, matched) {
|
|
|
40851
40896
|
}
|
|
40852
40897
|
function updateGuideContainer(containerId, context, pendo) {
|
|
40853
40898
|
if (pendo.designer && !pendo._.size(pendo.dom('#pendo-ps-substitution-icon'))) {
|
|
40854
|
-
pendo.dom(containerSelector).append(substitutionIcon('#999', '30px'));
|
|
40899
|
+
pendo.dom(guideMarkdownUtil.containerSelector).append(substitutionIcon('#999', '30px'));
|
|
40855
40900
|
}
|
|
40856
|
-
pendo.flexElement(pendo.dom(containerSelector));
|
|
40901
|
+
pendo.flexElement(pendo.dom(guideMarkdownUtil.containerSelector));
|
|
40857
40902
|
pendo.BuildingBlocks.BuildingBlockGuides.recalculateGuideHeight(containerId, context);
|
|
40858
40903
|
}
|
|
40859
40904
|
function findSubstitutableUrlsInJson(originalData, placeholderData = [], pendo) {
|
|
@@ -40894,7 +40939,7 @@ function findSubstitutableUrlsInJson(originalData, placeholderData = [], pendo)
|
|
|
40894
40939
|
return placeholderData;
|
|
40895
40940
|
}
|
|
40896
40941
|
function findSubstitutableElements(pendo) {
|
|
40897
|
-
let elements = pendo.dom(`${containerSelector} *:not(.pendo-inline-ui)`);
|
|
40942
|
+
let elements = pendo.dom(`${guideMarkdownUtil.containerSelector} *:not(.pendo-inline-ui)`);
|
|
40898
40943
|
return pendo._.chain(elements)
|
|
40899
40944
|
.filter(function (placeholder) {
|
|
40900
40945
|
const subRegex = new RegExp(guideMarkdownUtil.substitutionRegex);
|
|
@@ -41002,7 +41047,7 @@ const RequiredQuestions = {
|
|
|
41002
41047
|
});
|
|
41003
41048
|
}
|
|
41004
41049
|
});
|
|
41005
|
-
step.attachEvent(step.guideElement.find(
|
|
41050
|
+
step.attachEvent(step.guideElement.find(guideMarkdownUtil.containerSelector)[0], 'click', function (event) {
|
|
41006
41051
|
if (!event.target.classList.contains('_pendo-button')) {
|
|
41007
41052
|
evaluateRequiredQuestions(requiredQuestions);
|
|
41008
41053
|
}
|
|
@@ -41173,7 +41218,7 @@ const SkipToEligibleStep = {
|
|
|
41173
41218
|
script(step, guide, pendo) {
|
|
41174
41219
|
let isAdvanceIntercepted = false;
|
|
41175
41220
|
let isPreviousIntercepted = false;
|
|
41176
|
-
let guideContainer = step.guideElement.find(
|
|
41221
|
+
let guideContainer = step.guideElement.find(guideMarkdownUtil.containerSelector);
|
|
41177
41222
|
let guideContainerAriaLabel = guideContainer.attr('aria-label');
|
|
41178
41223
|
let stepNumberOrAuto = skipStepRegex.exec(guideContainerAriaLabel)[1];
|
|
41179
41224
|
if (guideContainer) {
|
|
@@ -41185,7 +41230,7 @@ const SkipToEligibleStep = {
|
|
|
41185
41230
|
let eligibleStep = findEligibleSkipStep(stepNumberOrAuto, 'next');
|
|
41186
41231
|
if (!isAdvanceIntercepted && stepNumberOrAuto) {
|
|
41187
41232
|
isAdvanceIntercepted = true;
|
|
41188
|
-
pendo.goToStep({ destinationStepId: eligibleStep.id });
|
|
41233
|
+
pendo.goToStep({ destinationStepId: eligibleStep.id, step });
|
|
41189
41234
|
evt.cancel = true;
|
|
41190
41235
|
}
|
|
41191
41236
|
});
|
|
@@ -41195,7 +41240,7 @@ const SkipToEligibleStep = {
|
|
|
41195
41240
|
let eligibleStep = findEligibleSkipStep(stepNumberOrAuto, 'previous');
|
|
41196
41241
|
if (!isPreviousIntercepted && stepNumberOrAuto) {
|
|
41197
41242
|
isPreviousIntercepted = true;
|
|
41198
|
-
pendo.goToStep({ destinationStepId: eligibleStep.id });
|
|
41243
|
+
pendo.goToStep({ destinationStepId: eligibleStep.id, step });
|
|
41199
41244
|
evt.cancel = true;
|
|
41200
41245
|
}
|
|
41201
41246
|
});
|
|
@@ -41205,10 +41250,10 @@ const SkipToEligibleStep = {
|
|
|
41205
41250
|
let skipForwardStep = findStepOnPage(guide.getPositionOfStep(step), 'next', stepNumber);
|
|
41206
41251
|
let skipPreviousStep = findStepOnPage(guide.getPositionOfStep(step) - 2, 'previous', stepNumber);
|
|
41207
41252
|
if (skipForwardStep && direction == 'next') {
|
|
41208
|
-
pendo.goToStep({ destinationStepId: skipForwardStep });
|
|
41253
|
+
pendo.goToStep({ destinationStepId: skipForwardStep, step });
|
|
41209
41254
|
}
|
|
41210
41255
|
if (skipPreviousStep && direction == 'previous') {
|
|
41211
|
-
pendo.goToStep({ destinationStepId: skipPreviousStep });
|
|
41256
|
+
pendo.goToStep({ destinationStepId: skipPreviousStep, step });
|
|
41212
41257
|
}
|
|
41213
41258
|
return direction === 'next' ? skipForwardStep : skipPreviousStep;
|
|
41214
41259
|
}
|
|
@@ -41234,7 +41279,7 @@ const SkipToEligibleStep = {
|
|
|
41234
41279
|
},
|
|
41235
41280
|
test(step, guide, pendo) {
|
|
41236
41281
|
var _a;
|
|
41237
|
-
const guideContainerAriaLabel = (_a = step.guideElement) === null || _a === void 0 ? void 0 : _a.find(
|
|
41282
|
+
const guideContainerAriaLabel = (_a = step.guideElement) === null || _a === void 0 ? void 0 : _a.find(guideMarkdownUtil.containerSelector).attr('aria-label');
|
|
41238
41283
|
return pendo._.isString(guideContainerAriaLabel) && guideContainerAriaLabel.indexOf('{skipStep') !== -1;
|
|
41239
41284
|
},
|
|
41240
41285
|
designerListener(pendo) {
|
|
@@ -41244,7 +41289,7 @@ const SkipToEligibleStep = {
|
|
|
41244
41289
|
attributes: true,
|
|
41245
41290
|
childList: true,
|
|
41246
41291
|
characterData: true,
|
|
41247
|
-
subtree:
|
|
41292
|
+
subtree: true
|
|
41248
41293
|
};
|
|
41249
41294
|
const MutationObserver = getZoneSafeMethod$1(pendo._, 'MutationObserver');
|
|
41250
41295
|
const observer = new MutationObserver(applySkipStepIndicator);
|
|
@@ -41255,14 +41300,14 @@ const SkipToEligibleStep = {
|
|
|
41255
41300
|
var _a, _b;
|
|
41256
41301
|
const nodeHasQuerySelector = pendo._.isFunction((_a = mutation.addedNodes[0]) === null || _a === void 0 ? void 0 : _a.querySelectorAll);
|
|
41257
41302
|
if (mutation.addedNodes.length && nodeHasQuerySelector) {
|
|
41258
|
-
let guideContainer = mutation.addedNodes[0].querySelectorAll(
|
|
41303
|
+
let guideContainer = mutation.addedNodes[0].querySelectorAll(guideMarkdownUtil.containerSelector);
|
|
41259
41304
|
let guideContainerAriaLabel = (_b = guideContainer[0]) === null || _b === void 0 ? void 0 : _b.getAttribute('aria-label');
|
|
41260
41305
|
if (guideContainerAriaLabel) {
|
|
41261
41306
|
if (guideContainerAriaLabel.match(skipStepRegex)) {
|
|
41262
41307
|
let fullSkipStepString = guideContainerAriaLabel.match(skipStepRegex)[0];
|
|
41263
41308
|
guideContainerAriaLabel.replace(fullSkipStepString, '');
|
|
41264
41309
|
if (!pendo.dom('#_pendoSkipIcon').length) {
|
|
41265
|
-
pendo.dom(
|
|
41310
|
+
pendo.dom(guideMarkdownUtil.containerSelector).append(skipIcon('#999', '30px').trim());
|
|
41266
41311
|
}
|
|
41267
41312
|
}
|
|
41268
41313
|
}
|
|
@@ -48566,16 +48611,17 @@ class SessionRecorderBuffer {
|
|
|
48566
48611
|
}
|
|
48567
48612
|
}
|
|
48568
48613
|
|
|
48569
|
-
const
|
|
48570
|
-
const
|
|
48614
|
+
const MAX_RETRY_DELAY_MS = 5 * 60 * 1000; // 5 minutes
|
|
48615
|
+
const ONE_HOUR = 60 * 60 * 1000; // 1 hour
|
|
48616
|
+
const FAILURE_WINDOW_MS = 2 * ONE_HOUR;
|
|
48571
48617
|
class SendQueue {
|
|
48572
|
-
constructor(sendFn
|
|
48618
|
+
constructor(sendFn) {
|
|
48573
48619
|
this.queue = [];
|
|
48574
48620
|
this.unloads = new Set();
|
|
48575
48621
|
this.pending = new Set();
|
|
48576
48622
|
this.failures = new Map();
|
|
48623
|
+
this.firstFailureTime = null;
|
|
48577
48624
|
this.sendFn = sendFn;
|
|
48578
|
-
this.maxFailures = maxFailures;
|
|
48579
48625
|
}
|
|
48580
48626
|
isEmpty() {
|
|
48581
48627
|
return this.queue.length <= 0;
|
|
@@ -48585,6 +48631,7 @@ class SendQueue {
|
|
|
48585
48631
|
this.unloads.clear();
|
|
48586
48632
|
this.pending.clear();
|
|
48587
48633
|
this.failures.clear();
|
|
48634
|
+
this.firstFailureTime = null;
|
|
48588
48635
|
this.stopped = true;
|
|
48589
48636
|
clearTimeout(this.timer);
|
|
48590
48637
|
delete this.timer;
|
|
@@ -48605,12 +48652,16 @@ class SendQueue {
|
|
|
48605
48652
|
incrementFailure(payload) {
|
|
48606
48653
|
const failureCount = (this.failures.get(payload) || 0) + 1;
|
|
48607
48654
|
this.failures.set(payload, failureCount);
|
|
48655
|
+
if (this.firstFailureTime == null) {
|
|
48656
|
+
this.firstFailureTime = new Date().getTime();
|
|
48657
|
+
}
|
|
48608
48658
|
return failureCount;
|
|
48609
48659
|
}
|
|
48610
48660
|
pass(payload, dequeue = true) {
|
|
48611
48661
|
this.unloads.delete(payload);
|
|
48612
48662
|
this.pending.delete(payload);
|
|
48613
|
-
this.failures.
|
|
48663
|
+
this.failures.delete(payload);
|
|
48664
|
+
this.firstFailureTime = null;
|
|
48614
48665
|
const index = this.queue.indexOf(payload);
|
|
48615
48666
|
if (index >= 0) {
|
|
48616
48667
|
this.queue.splice(index, 1);
|
|
@@ -48625,18 +48676,26 @@ class SendQueue {
|
|
|
48625
48676
|
const failureCount = this.incrementFailure(payload);
|
|
48626
48677
|
if (this.stopped || !retry)
|
|
48627
48678
|
return;
|
|
48628
|
-
|
|
48679
|
+
const now = new Date().getTime();
|
|
48680
|
+
const elapsed = now - (this.firstFailureTime || now);
|
|
48681
|
+
if (elapsed >= FAILURE_WINDOW_MS) {
|
|
48629
48682
|
if (this.onTimeout) {
|
|
48630
48683
|
this.onTimeout();
|
|
48631
48684
|
}
|
|
48632
|
-
this.
|
|
48685
|
+
this.firstFailureTime = null;
|
|
48686
|
+
this.retryLater(ONE_HOUR);
|
|
48687
|
+
return;
|
|
48633
48688
|
}
|
|
48634
|
-
this.retryLater(Math.pow(2,
|
|
48689
|
+
this.retryLater(Math.min(Math.pow(2, failureCount - 1) * 1000, MAX_RETRY_DELAY_MS));
|
|
48690
|
+
}
|
|
48691
|
+
retryNow() {
|
|
48692
|
+
clearTimeout(this.timer);
|
|
48693
|
+
delete this.timer;
|
|
48694
|
+
this.next();
|
|
48635
48695
|
}
|
|
48636
48696
|
retryLater(delay) {
|
|
48637
48697
|
this.timer = setTimeout$1(() => {
|
|
48638
|
-
|
|
48639
|
-
this.next();
|
|
48698
|
+
this.retryNow();
|
|
48640
48699
|
}, delay);
|
|
48641
48700
|
}
|
|
48642
48701
|
failed() {
|
|
@@ -48651,7 +48710,7 @@ class SendQueue {
|
|
|
48651
48710
|
}
|
|
48652
48711
|
drain(finalPayloadArray, isUnload = true) {
|
|
48653
48712
|
this.queue.push(...finalPayloadArray);
|
|
48654
|
-
if (this.failed())
|
|
48713
|
+
if (this.failed() && !this.allowDrainWhileFailed)
|
|
48655
48714
|
return Promise$2.reject();
|
|
48656
48715
|
const promises = [];
|
|
48657
48716
|
for (const payload of this.queue) {
|
|
@@ -56940,7 +56999,6 @@ var ConfigReader = (function () {
|
|
|
56940
56999
|
* @type {number}
|
|
56941
57000
|
*/
|
|
56942
57001
|
addOption('guideSeenTimeoutLength', [PENDO_CONFIG_SRC, SNIPPET_SRC], 10000);
|
|
56943
|
-
// addOption('guideTimeout', [SNIPPET_SRC]); // old, use guides.timeout instead
|
|
56944
57002
|
/**
|
|
56945
57003
|
* If `true`, guides will be verified against their saved content hash before display to ensure validity of
|
|
56946
57004
|
* guide content.
|