@pendo/agent 2.296.0 → 2.297.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 +2 -1
- package/dist/pendo.module.js +233 -90
- package/dist/pendo.module.min.js +9 -9
- package/dist/servers.json +7 -7
- package/package.json +1 -1
package/dist/dom.esm.js
CHANGED
|
@@ -6164,6 +6164,7 @@ var ConfigReader = (function () {
|
|
|
6164
6164
|
*/
|
|
6165
6165
|
addOption('additionalApiKeys', [PENDO_CONFIG_SRC, SNIPPET_SRC]);
|
|
6166
6166
|
addOption('allowedOriginServers');
|
|
6167
|
+
addOption('allowedOriginServerHashes');
|
|
6167
6168
|
addOption('allowMixedApiKeyFrames', [SNIPPET_SRC, PENDO_CONFIG_SRC], true);
|
|
6168
6169
|
/**
|
|
6169
6170
|
* A function that returns either an array of strings or an object to decorate the url for events.
|
|
@@ -7313,7 +7314,7 @@ function getScreenPosition(element) {
|
|
|
7313
7314
|
};
|
|
7314
7315
|
}
|
|
7315
7316
|
|
|
7316
|
-
var VERSION = '2.
|
|
7317
|
+
var VERSION = '2.297.0_';
|
|
7317
7318
|
|
|
7318
7319
|
var decodeURIComponent = _.isFunction(window.decodeURIComponent) ? window.decodeURIComponent : _.identity;
|
|
7319
7320
|
|
package/dist/pendo.module.js
CHANGED
|
@@ -488,51 +488,62 @@ function getAlternateAgentUrl(config, useStaging, debuggingEnabled) {
|
|
|
488
488
|
}
|
|
489
489
|
return agentUrl;
|
|
490
490
|
}
|
|
491
|
-
function
|
|
492
|
-
if (!
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
if (!location) {
|
|
499
|
-
location = window.location;
|
|
500
|
-
}
|
|
501
|
-
// trying to not calculate Hash if not needed.
|
|
502
|
-
if (hasHashedStagingServers(config)) {
|
|
503
|
-
var hostHash = getHash(location.host);
|
|
504
|
-
for (var j = 0, jj = config[STAGING_SERVER_HASHES].length; j < jj; ++j) {
|
|
505
|
-
var h = config[STAGING_SERVER_HASHES][j];
|
|
506
|
-
if (h === hostHash) {
|
|
491
|
+
function urlMatchesPatterns(url, patterns = [], hashes = []) {
|
|
492
|
+
if (!url)
|
|
493
|
+
return false;
|
|
494
|
+
if (hashes.length > 0) {
|
|
495
|
+
const urlHash = getHash(url);
|
|
496
|
+
for (let i = 0, x = hashes.length; i < x; ++i) {
|
|
497
|
+
if (hashes[i] === urlHash) {
|
|
507
498
|
return true;
|
|
508
499
|
}
|
|
509
500
|
}
|
|
510
501
|
}
|
|
511
|
-
if (
|
|
512
|
-
for (
|
|
513
|
-
|
|
514
|
-
if (typeof
|
|
515
|
-
|
|
502
|
+
if (patterns.length > 0) {
|
|
503
|
+
for (let j = 0, y = patterns.length; j < y; ++j) {
|
|
504
|
+
let pattern = patterns[j];
|
|
505
|
+
if (typeof pattern === 'object' && pattern.value) {
|
|
506
|
+
if (pattern.regexp) {
|
|
507
|
+
if (pattern.value.startsWith('/') && pattern.value.endsWith('/')) {
|
|
508
|
+
pattern.value = pattern.value.substring(1, pattern.value.length - 1);
|
|
509
|
+
}
|
|
510
|
+
pattern = new RegExp(pattern.value);
|
|
511
|
+
}
|
|
512
|
+
else {
|
|
513
|
+
pattern = pattern.value;
|
|
514
|
+
}
|
|
516
515
|
}
|
|
517
|
-
if (
|
|
516
|
+
if (typeof pattern === 'string') {
|
|
517
|
+
pattern = new RegExp('^' + pattern + '$');
|
|
518
|
+
}
|
|
519
|
+
if (pattern instanceof RegExp && pattern.test(url)) {
|
|
518
520
|
return true;
|
|
519
521
|
}
|
|
520
522
|
}
|
|
521
523
|
}
|
|
522
524
|
return false;
|
|
523
525
|
}
|
|
526
|
+
function isStagingServer(config, location) {
|
|
527
|
+
if (!config) {
|
|
528
|
+
config = getPendoConfig();
|
|
529
|
+
}
|
|
530
|
+
if (!config) {
|
|
531
|
+
return false;
|
|
532
|
+
}
|
|
533
|
+
if (isStagingEnvironment(config)) {
|
|
534
|
+
return true;
|
|
535
|
+
}
|
|
536
|
+
if (!location) {
|
|
537
|
+
location = window.location;
|
|
538
|
+
}
|
|
539
|
+
return urlMatchesPatterns(location.host, config.stagingServers, config[STAGING_SERVER_HASHES]);
|
|
540
|
+
}
|
|
524
541
|
function getHash(str) {
|
|
525
542
|
return b64.uint8ToBase64(sha1
|
|
526
543
|
.create()
|
|
527
544
|
.update(str)
|
|
528
545
|
.digest());
|
|
529
546
|
}
|
|
530
|
-
function hasHashedStagingServers(config) {
|
|
531
|
-
return config && config.stagingAgentUrl && config[STAGING_SERVER_HASHES];
|
|
532
|
-
}
|
|
533
|
-
function hasStagingServerConfig(config) {
|
|
534
|
-
return config && config.stagingAgentUrl && config.stagingServers;
|
|
535
|
-
}
|
|
536
547
|
var METHODS_TO_CAPTURE = [
|
|
537
548
|
'initialize',
|
|
538
549
|
'identify',
|
|
@@ -2790,6 +2801,7 @@ var ConfigReader = (function () {
|
|
|
2790
2801
|
*/
|
|
2791
2802
|
addOption('additionalApiKeys', [PENDO_CONFIG_SRC, SNIPPET_SRC]);
|
|
2792
2803
|
addOption('allowedOriginServers');
|
|
2804
|
+
addOption('allowedOriginServerHashes');
|
|
2793
2805
|
addOption('allowMixedApiKeyFrames', [SNIPPET_SRC, PENDO_CONFIG_SRC], true);
|
|
2794
2806
|
/**
|
|
2795
2807
|
* A function that returns either an array of strings or an object to decorate the url for events.
|
|
@@ -3892,8 +3904,8 @@ let SERVER = '';
|
|
|
3892
3904
|
let ASSET_HOST = '';
|
|
3893
3905
|
let ASSET_PATH = '';
|
|
3894
3906
|
let DESIGNER_SERVER = '';
|
|
3895
|
-
let VERSION = '2.
|
|
3896
|
-
let PACKAGE_VERSION = '2.
|
|
3907
|
+
let VERSION = '2.297.0_';
|
|
3908
|
+
let PACKAGE_VERSION = '2.297.0';
|
|
3897
3909
|
let LOADER = 'xhr';
|
|
3898
3910
|
/* eslint-enable agent-eslint-rules/no-gulp-env-references */
|
|
3899
3911
|
/**
|
|
@@ -3928,9 +3940,6 @@ function isProdAgent() {
|
|
|
3928
3940
|
function isRCAgent() {
|
|
3929
3941
|
return ENV.indexOf('rc') !== -1;
|
|
3930
3942
|
}
|
|
3931
|
-
function isBetaAgent(config) {
|
|
3932
|
-
return !isProdAgent() || isStagingServer(config);
|
|
3933
|
-
}
|
|
3934
3943
|
|
|
3935
3944
|
var rtrim = /^\s+|\s+$/g;
|
|
3936
3945
|
var trim = String.prototype.trim;
|
|
@@ -9533,12 +9542,15 @@ function exportDataHost(pendo) {
|
|
|
9533
9542
|
pendo.HOST = HOST;
|
|
9534
9543
|
}
|
|
9535
9544
|
function getAssetHost() {
|
|
9545
|
+
return ConfigReader.get('assetHost') || getContentHost();
|
|
9546
|
+
}
|
|
9547
|
+
function getContentHost() {
|
|
9536
9548
|
var protocol = 'https://';
|
|
9537
|
-
var
|
|
9538
|
-
if (
|
|
9539
|
-
|
|
9549
|
+
var contentHost = ConfigReader.get('contentHost') || ASSET_HOST;
|
|
9550
|
+
if (contentHost && contentHost.indexOf('://') === -1) {
|
|
9551
|
+
contentHost = protocol + contentHost;
|
|
9540
9552
|
}
|
|
9541
|
-
return
|
|
9553
|
+
return contentHost;
|
|
9542
9554
|
}
|
|
9543
9555
|
function isLocalAgent(assetHost) {
|
|
9544
9556
|
return assetHost.indexOf('localhost') >= 0 || assetHost.indexOf('local.pendo.io') >= 0;
|
|
@@ -9779,11 +9791,9 @@ function writeErrorPOST(msg) {
|
|
|
9779
9791
|
* @returns void
|
|
9780
9792
|
*/
|
|
9781
9793
|
function writeMetricsPOST(payload) {
|
|
9782
|
-
if (_.size(payload).length < 1)
|
|
9783
|
-
return;
|
|
9784
9794
|
try {
|
|
9785
9795
|
const url = `${HOST}/data/agentmetrics?apiKey=${pendo$1.apiKey}`;
|
|
9786
|
-
log.debug(`Will send ${payload} to ${url} using ${fetchKeepalive.supported() ? 'fetch' : 'xhr'} once the endpoint exists`);
|
|
9796
|
+
log.debug(`Will send ${JSON.stringify(payload)} to ${url} using ${fetchKeepalive.supported() ? 'fetch' : 'xhr'} once the endpoint exists`);
|
|
9787
9797
|
if (fetchKeepalive.supported()) {
|
|
9788
9798
|
// fetch(url, {
|
|
9789
9799
|
// method: 'POST',
|
|
@@ -11435,11 +11445,13 @@ function isTrustedOrigin(host) {
|
|
|
11435
11445
|
// for CNAME, trust the top-level origin
|
|
11436
11446
|
if (host === window.location.origin)
|
|
11437
11447
|
return true;
|
|
11438
|
-
// Trust the
|
|
11448
|
+
// Trust the configured hosts
|
|
11439
11449
|
if (host === getDataHost())
|
|
11440
11450
|
return true;
|
|
11441
11451
|
if (host === getAssetHost())
|
|
11442
11452
|
return true;
|
|
11453
|
+
if (host === getContentHost())
|
|
11454
|
+
return true;
|
|
11443
11455
|
// Domains that Pendo owns, will be swapped in by build patches
|
|
11444
11456
|
const patterns = [
|
|
11445
11457
|
/^https:\/\/(adopt\.)?((us1)\.)?(app|via|adopt|cdn)(\.(au|eu|gov|hsbc|jpn))?\.pendo\.io$/,
|
|
@@ -11458,12 +11470,20 @@ function isTrustedOrigin(host) {
|
|
|
11458
11470
|
if (host === fullHostname)
|
|
11459
11471
|
return true;
|
|
11460
11472
|
}
|
|
11461
|
-
if (
|
|
11473
|
+
if (urlMatchesPatterns(host, ConfigReader.get('allowedOriginServers', []), ConfigReader.get('allowedOriginServerHashes', [])))
|
|
11462
11474
|
return true;
|
|
11463
11475
|
return _.any(patterns, function (pattern) {
|
|
11464
11476
|
return pattern.test(host);
|
|
11465
11477
|
});
|
|
11466
11478
|
}
|
|
11479
|
+
function hasAllowedOriginServers() {
|
|
11480
|
+
const allowedOriginServers = ConfigReader.get('allowedOriginServers', []);
|
|
11481
|
+
return allowedOriginServers && allowedOriginServers.length > 0;
|
|
11482
|
+
}
|
|
11483
|
+
function hasHashedAllowedOriginServers() {
|
|
11484
|
+
const allowedOriginServerHashes = ConfigReader.get('allowedOriginServerHashes', []);
|
|
11485
|
+
return allowedOriginServerHashes && allowedOriginServerHashes.length > 0;
|
|
11486
|
+
}
|
|
11467
11487
|
|
|
11468
11488
|
function parseUrl(url) {
|
|
11469
11489
|
if (!_.isString(url))
|
|
@@ -11497,9 +11517,9 @@ function addIntegrityAttribute(element, url) {
|
|
|
11497
11517
|
}
|
|
11498
11518
|
}
|
|
11499
11519
|
var trustedOriginForLoadResource = function (origin) {
|
|
11500
|
-
var noAllowedOriginServers =
|
|
11520
|
+
var noAllowedOriginServers = !hasAllowedOriginServers() && !hasHashedAllowedOriginServers();
|
|
11501
11521
|
var isAdoptPartner = treatAsAdoptPartner();
|
|
11502
|
-
if (noAllowedOriginServers || isAdoptPartner
|
|
11522
|
+
if (noAllowedOriginServers || isAdoptPartner) {
|
|
11503
11523
|
return true;
|
|
11504
11524
|
}
|
|
11505
11525
|
return isTrustedOrigin(origin);
|
|
@@ -12261,13 +12281,19 @@ class PerformanceMonitor {
|
|
|
12261
12281
|
});
|
|
12262
12282
|
}
|
|
12263
12283
|
send() {
|
|
12264
|
-
const
|
|
12284
|
+
const metrics = _.reduce(_.keys(Metrics), (acc, name) => {
|
|
12265
12285
|
const entries = performance.getEntriesByName(name);
|
|
12266
|
-
const
|
|
12267
|
-
acc
|
|
12268
|
-
|
|
12286
|
+
const value = Metrics[name].instrument(entries);
|
|
12287
|
+
acc.push({ name, value });
|
|
12288
|
+
return acc;
|
|
12289
|
+
}, []);
|
|
12290
|
+
const payload = _.filter(metrics, (metric) => {
|
|
12291
|
+
return metric.value > 0;
|
|
12292
|
+
});
|
|
12269
12293
|
this._clearMarksAndMeasures();
|
|
12270
|
-
|
|
12294
|
+
if (_.size(payload)) {
|
|
12295
|
+
writeMetricsPOST(payload);
|
|
12296
|
+
}
|
|
12271
12297
|
}
|
|
12272
12298
|
_checkPerformanceApi() {
|
|
12273
12299
|
return ConfigReader.get('performanceMetricsEnabled') &&
|
|
@@ -12300,11 +12326,14 @@ class PerformanceMonitor {
|
|
|
12300
12326
|
}
|
|
12301
12327
|
}
|
|
12302
12328
|
_clearMarksAndMeasures() {
|
|
12303
|
-
|
|
12329
|
+
// TODO: fix custom lint rule to handle sets
|
|
12330
|
+
// eslint-disable-next-line agent-eslint-rules/no-array-foreach
|
|
12331
|
+
this.marks.forEach(name => {
|
|
12304
12332
|
performance.clearMarks(name);
|
|
12305
12333
|
});
|
|
12306
12334
|
this.marks.clear();
|
|
12307
|
-
|
|
12335
|
+
// eslint-disable-next-line agent-eslint-rules/no-array-foreach
|
|
12336
|
+
this.measures.forEach(name => {
|
|
12308
12337
|
performance.clearMeasures(name);
|
|
12309
12338
|
});
|
|
12310
12339
|
this.measures.clear();
|
|
@@ -13112,8 +13141,10 @@ var extractAttribute = function (element, attrName, type) {
|
|
|
13112
13141
|
var tag = element.nodeName.toLowerCase();
|
|
13113
13142
|
if ((tag == 'img' && attrName == 'src') ||
|
|
13114
13143
|
(tag == 'a' && attrName == 'href')) {
|
|
13115
|
-
|
|
13116
|
-
|
|
13144
|
+
if (useLegacyGetHref()) {
|
|
13145
|
+
var src = element.getAttribute(attrName);
|
|
13146
|
+
return sanitizeUrl(handleEmbeddedData(src));
|
|
13147
|
+
}
|
|
13117
13148
|
}
|
|
13118
13149
|
var attr = getAttributeValue(element, attrName);
|
|
13119
13150
|
if (type && typeof attr !== type)
|
|
@@ -16301,8 +16332,19 @@ var BuildingBlockTooltips = (function () {
|
|
|
16301
16332
|
offset: TOOLTIP_CONSTANTS.DEFAULT_CARET_OFFSET,
|
|
16302
16333
|
borderWidth: 0
|
|
16303
16334
|
};
|
|
16304
|
-
|
|
16305
|
-
|
|
16335
|
+
// Check for border in dark mode properties first, then fall back to regular properties
|
|
16336
|
+
var borderSource = null;
|
|
16337
|
+
var regularBorder = _.get(containerDomJson, 'props.style.border');
|
|
16338
|
+
var darkModeBorder = _.get(containerDomJson, 'darkModeProps.style.border');
|
|
16339
|
+
// Use dark mode properties if step.isDarkMode is true and dark mode properties exist
|
|
16340
|
+
if (step && step.isDarkMode && darkModeBorder) {
|
|
16341
|
+
borderSource = darkModeBorder;
|
|
16342
|
+
}
|
|
16343
|
+
else if (regularBorder) {
|
|
16344
|
+
borderSource = regularBorder;
|
|
16345
|
+
}
|
|
16346
|
+
if (borderSource) {
|
|
16347
|
+
var guideBorderArray = borderSource.split(' ');
|
|
16306
16348
|
caretDimensions.borderColor = guideBorderArray[2];
|
|
16307
16349
|
caretDimensions.borderWidth = parseInt(guideBorderArray[0], 10) || 0;
|
|
16308
16350
|
}
|
|
@@ -21968,6 +22010,7 @@ function startPreviewMode(window) {
|
|
|
21968
22010
|
if (isInDesignerPreviewMode()) {
|
|
21969
22011
|
const pendoConfig = getPendoConfig();
|
|
21970
22012
|
pendoConfig.allowedOriginServers = [];
|
|
22013
|
+
pendoConfig.allowedOriginServerHashes = [];
|
|
21971
22014
|
}
|
|
21972
22015
|
Events.startPreview.trigger();
|
|
21973
22016
|
Events.leaderChanged.on(function (e) {
|
|
@@ -24928,7 +24971,7 @@ var _addCredits = function (elem) {
|
|
|
24928
24971
|
return;
|
|
24929
24972
|
}
|
|
24930
24973
|
var img = document.createElement('img');
|
|
24931
|
-
img.setAttribute('src',
|
|
24974
|
+
img.setAttribute('src', getContentHost() + '/img/tiny-logo.png');
|
|
24932
24975
|
var credits = dom(document.createElement('div')).addClass('_pendo-credits_')
|
|
24933
24976
|
.css({
|
|
24934
24977
|
bottom: 0,
|
|
@@ -26383,6 +26426,9 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
26383
26426
|
};
|
|
26384
26427
|
|
|
26385
26428
|
const PENDO_HEADERS_KEY = '_pendoHeaders';
|
|
26429
|
+
function getTransformedUrl(url) {
|
|
26430
|
+
return store.getters['networkUrl/getTransformedUrl']()(url);
|
|
26431
|
+
}
|
|
26386
26432
|
class NetworkRequestIntercept {
|
|
26387
26433
|
entriesToObject(entries) {
|
|
26388
26434
|
const obj = {};
|
|
@@ -26475,6 +26521,7 @@ class NetworkRequestIntercept {
|
|
|
26475
26521
|
window.fetch = function (...args) {
|
|
26476
26522
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26477
26523
|
const [url, config = {}] = args;
|
|
26524
|
+
const transformedUrl = getTransformedUrl(url);
|
|
26478
26525
|
const method = config.method || 'GET';
|
|
26479
26526
|
const requestId = networkInterceptor.generateRequestId();
|
|
26480
26527
|
// Capture request data
|
|
@@ -26483,7 +26530,7 @@ class NetworkRequestIntercept {
|
|
|
26483
26530
|
const body = networkInterceptor.safelySerializeBody(config.body);
|
|
26484
26531
|
_.each(networkInterceptor.callbackFns, ({ request }) => {
|
|
26485
26532
|
if (_.isFunction(request))
|
|
26486
|
-
request({ requestId, method, url, body, headers });
|
|
26533
|
+
request({ requestId, method, url: transformedUrl, body, headers });
|
|
26487
26534
|
});
|
|
26488
26535
|
}
|
|
26489
26536
|
catch (e) {
|
|
@@ -26510,7 +26557,7 @@ class NetworkRequestIntercept {
|
|
|
26510
26557
|
statusText,
|
|
26511
26558
|
body: responseBody,
|
|
26512
26559
|
headers,
|
|
26513
|
-
url,
|
|
26560
|
+
url: transformedUrl,
|
|
26514
26561
|
method
|
|
26515
26562
|
});
|
|
26516
26563
|
}
|
|
@@ -26534,7 +26581,7 @@ class NetworkRequestIntercept {
|
|
|
26534
26581
|
statusText: 'Network Error',
|
|
26535
26582
|
headers: {},
|
|
26536
26583
|
body: null,
|
|
26537
|
-
url,
|
|
26584
|
+
url: transformedUrl,
|
|
26538
26585
|
method,
|
|
26539
26586
|
error: error.message
|
|
26540
26587
|
});
|
|
@@ -26556,8 +26603,9 @@ class NetworkRequestIntercept {
|
|
|
26556
26603
|
return networkInterceptor._originalSetRequestHeader.apply(this, arguments);
|
|
26557
26604
|
};
|
|
26558
26605
|
XMLHttpRequest.prototype.open = function (method, url) {
|
|
26606
|
+
const transformedUrl = getTransformedUrl(url);
|
|
26559
26607
|
this._method = method;
|
|
26560
|
-
this._url =
|
|
26608
|
+
this._url = transformedUrl;
|
|
26561
26609
|
this._requestId = networkInterceptor.generateRequestId();
|
|
26562
26610
|
return networkInterceptor._originalXHROpen.apply(this, arguments);
|
|
26563
26611
|
};
|
|
@@ -29656,8 +29704,21 @@ var attrActionEnum = {
|
|
|
29656
29704
|
href: ['Replace', 'ForceSecure'],
|
|
29657
29705
|
protocol: ['ForceSecure']
|
|
29658
29706
|
};
|
|
29659
|
-
const TARGETS = ['location', 'attribute', 'both'];
|
|
29707
|
+
const TARGETS = ['location', 'attribute', 'both', 'network', 'all'];
|
|
29660
29708
|
const DEFAULT_TARGET = 'location';
|
|
29709
|
+
function normalizeTarget(target) {
|
|
29710
|
+
if (_.isArray(target)) {
|
|
29711
|
+
// Filter out invalid targets and fallback to DEFAULT_TARGET if empty
|
|
29712
|
+
const validTargets = _.filter(target, function (t) {
|
|
29713
|
+
return TARGETS.indexOf(t) >= 0;
|
|
29714
|
+
});
|
|
29715
|
+
return validTargets.length > 0 ? validTargets : [DEFAULT_TARGET];
|
|
29716
|
+
}
|
|
29717
|
+
if (TARGETS.indexOf(target) >= 0) {
|
|
29718
|
+
return target;
|
|
29719
|
+
}
|
|
29720
|
+
return DEFAULT_TARGET;
|
|
29721
|
+
}
|
|
29661
29722
|
function UrlTransform(attr, action, data, target) {
|
|
29662
29723
|
if (_.isObject(attr)) {
|
|
29663
29724
|
action = attr.action;
|
|
@@ -29673,14 +29734,11 @@ function UrlTransform(attr, action, data, target) {
|
|
|
29673
29734
|
var validActions = attrActionEnum[attr].join(', ');
|
|
29674
29735
|
throw new Error('Invalid transform action: "' + action + '" for attribute "' + attr + '". Valid actions for "' + attr + '" are: ' + validActions + '. Example: {attr: "' + attr + '", action: "' + attrActionEnum[attr][0] + '", data: ...}');
|
|
29675
29736
|
}
|
|
29676
|
-
// validate 'target'
|
|
29677
|
-
if (TARGETS.indexOf(target) < 0) {
|
|
29678
|
-
target = DEFAULT_TARGET;
|
|
29679
|
-
}
|
|
29680
29737
|
this.attr = attr;
|
|
29681
29738
|
this.action = action;
|
|
29682
29739
|
this.data = data;
|
|
29683
|
-
|
|
29740
|
+
// validate and normalize target
|
|
29741
|
+
this.target = normalizeTarget(target);
|
|
29684
29742
|
}
|
|
29685
29743
|
UrlTransform.prototype.applyTo = function (url) {
|
|
29686
29744
|
var actionImpls = {
|
|
@@ -29878,12 +29936,16 @@ var LocationModule = (function (global) {
|
|
|
29878
29936
|
addTransforms(context, transforms) {
|
|
29879
29937
|
_.each(transforms, function (f) {
|
|
29880
29938
|
const t = UrlTransform.fromJSON(f);
|
|
29881
|
-
|
|
29939
|
+
const targets = _.isArray(t.target) ? t.target : [t.target];
|
|
29940
|
+
if (_.contains(targets, 'location') || _.contains(targets, 'both') || _.contains(targets, 'all')) {
|
|
29882
29941
|
context.commit('addTransform', t);
|
|
29883
29942
|
}
|
|
29884
|
-
if (
|
|
29943
|
+
if (_.contains(targets, 'attribute') || _.contains(targets, 'both') || _.contains(targets, 'all')) {
|
|
29885
29944
|
store.dispatch('nodeAttr/addAttrTransform', t);
|
|
29886
29945
|
}
|
|
29946
|
+
if (_.contains(targets, 'network') || _.contains(targets, 'all')) {
|
|
29947
|
+
store.dispatch('networkUrl/addNetworkTransform', t);
|
|
29948
|
+
}
|
|
29887
29949
|
});
|
|
29888
29950
|
},
|
|
29889
29951
|
addInternalTransforms(context, transforms) {
|
|
@@ -29922,6 +29984,7 @@ var LocationModule = (function (global) {
|
|
|
29922
29984
|
clearTransforms(state) {
|
|
29923
29985
|
state.transforms = [];
|
|
29924
29986
|
store.commit('nodeAttr/clearURLTransforms');
|
|
29987
|
+
store.commit('networkUrl/clearURLTransforms');
|
|
29925
29988
|
},
|
|
29926
29989
|
clearInternalTransforms(state) {
|
|
29927
29990
|
state.internalTransforms = [];
|
|
@@ -33795,6 +33858,7 @@ const DebuggerModule = (() => {
|
|
|
33795
33858
|
};
|
|
33796
33859
|
})();
|
|
33797
33860
|
|
|
33861
|
+
const URL_ATTR_NAMES = ['src', 'href'];
|
|
33798
33862
|
const NodeAttrModule = (function (global) {
|
|
33799
33863
|
const state = {
|
|
33800
33864
|
transforms: []
|
|
@@ -33828,11 +33892,14 @@ const NodeAttrModule = (function (global) {
|
|
|
33828
33892
|
};
|
|
33829
33893
|
const getters = {
|
|
33830
33894
|
getAttribute(state) {
|
|
33831
|
-
return function (element, attrName) {
|
|
33895
|
+
return function (element, attrName = '') {
|
|
33832
33896
|
let attrValue = element.getAttribute ? element.getAttribute(attrName) : element[attrName];
|
|
33833
33897
|
if (_.size(state.transforms) < 1) {
|
|
33834
33898
|
return attrValue;
|
|
33835
33899
|
}
|
|
33900
|
+
if (URL_ATTR_NAMES.indexOf(attrName.toLowerCase()) === -1) {
|
|
33901
|
+
return attrValue;
|
|
33902
|
+
}
|
|
33836
33903
|
try {
|
|
33837
33904
|
let url = resolveAttrValueAsURL(attrValue);
|
|
33838
33905
|
url = _.reduce([
|
|
@@ -33857,6 +33924,54 @@ const NodeAttrModule = (function (global) {
|
|
|
33857
33924
|
};
|
|
33858
33925
|
})();
|
|
33859
33926
|
|
|
33927
|
+
const NetworkUrlModule = (function (global) {
|
|
33928
|
+
const state = {
|
|
33929
|
+
transforms: []
|
|
33930
|
+
};
|
|
33931
|
+
const actions = {
|
|
33932
|
+
addNetworkTransform(context, urlTransform) {
|
|
33933
|
+
context.commit('addTransform', urlTransform);
|
|
33934
|
+
}
|
|
33935
|
+
};
|
|
33936
|
+
const mutations = {
|
|
33937
|
+
addTransform(state, transform) {
|
|
33938
|
+
state.transforms.push(transform);
|
|
33939
|
+
},
|
|
33940
|
+
clearURLTransforms(state) {
|
|
33941
|
+
state.transforms = [];
|
|
33942
|
+
}
|
|
33943
|
+
};
|
|
33944
|
+
const applyTransforms = (transforms, url) => {
|
|
33945
|
+
return _.reduce(transforms, function (tUrl, f) {
|
|
33946
|
+
return f.applyTo(tUrl);
|
|
33947
|
+
}, url);
|
|
33948
|
+
};
|
|
33949
|
+
const getters = {
|
|
33950
|
+
getTransformedUrl(state) {
|
|
33951
|
+
return function (url) {
|
|
33952
|
+
if (_.size(state.transforms) < 1) {
|
|
33953
|
+
return url;
|
|
33954
|
+
}
|
|
33955
|
+
try {
|
|
33956
|
+
let urlObj = url instanceof URL ? url : new URL(url, window.location.origin);
|
|
33957
|
+
urlObj = applyTransforms(state.transforms, urlObj);
|
|
33958
|
+
return urlObj.href;
|
|
33959
|
+
}
|
|
33960
|
+
catch (e) {
|
|
33961
|
+
log.critical(e);
|
|
33962
|
+
return url;
|
|
33963
|
+
}
|
|
33964
|
+
};
|
|
33965
|
+
}
|
|
33966
|
+
};
|
|
33967
|
+
return {
|
|
33968
|
+
state,
|
|
33969
|
+
actions,
|
|
33970
|
+
mutations,
|
|
33971
|
+
getters
|
|
33972
|
+
};
|
|
33973
|
+
})();
|
|
33974
|
+
|
|
33860
33975
|
function registerModules(store) {
|
|
33861
33976
|
store.registerModule('debugger', DebuggerModule);
|
|
33862
33977
|
store.registerModule('errorLog', ErrorLogModule);
|
|
@@ -33868,6 +33983,7 @@ function registerModules(store) {
|
|
|
33868
33983
|
store.registerModule('metadata', MetadataModule);
|
|
33869
33984
|
store.registerModule('preview', PreviewModule);
|
|
33870
33985
|
store.registerModule('nodeAttr', NodeAttrModule);
|
|
33986
|
+
store.registerModule('networkUrl', NetworkUrlModule);
|
|
33871
33987
|
}
|
|
33872
33988
|
|
|
33873
33989
|
const IFrameMonitor = (function () {
|
|
@@ -36597,7 +36713,7 @@ var Branding = (function () {
|
|
|
36597
36713
|
link.href = 'https://www.pendo.io/pendo-free/nps?utm_source=pendo_app&utm_medium=branded-nps&utm_campaign=free-branded-nps';
|
|
36598
36714
|
link.target = '_blank';
|
|
36599
36715
|
var img = document.createElement('img');
|
|
36600
|
-
img.setAttribute('src',
|
|
36716
|
+
img.setAttribute('src', getContentHost() + '/img/nps-branding.png');
|
|
36601
36717
|
link.appendChild(img);
|
|
36602
36718
|
link.style.display = 'inline-block';
|
|
36603
36719
|
var div = document.createElement('div');
|
|
@@ -36845,6 +36961,7 @@ const EventProperties = (function () {
|
|
|
36845
36961
|
let cepFailureCount;
|
|
36846
36962
|
let collectionThreshold;
|
|
36847
36963
|
const MAX_CONSECUTIVE_FAILURES = 3;
|
|
36964
|
+
const EVENT_PROPERTY_TIMEOUT = 'eventPropertyTimeout';
|
|
36848
36965
|
const collectClickEventProperties = makeSafe(createClickEventProperties);
|
|
36849
36966
|
const collectPageEventProperties = makeSafe(createPageEventProperties);
|
|
36850
36967
|
return {
|
|
@@ -36864,20 +36981,37 @@ const EventProperties = (function () {
|
|
|
36864
36981
|
pageEventPropertiesTimeout = false;
|
|
36865
36982
|
pepFailureCount = 0;
|
|
36866
36983
|
cepFailureCount = 0;
|
|
36867
|
-
|
|
36984
|
+
var configReader = PluginAPI.ConfigReader;
|
|
36985
|
+
/**
|
|
36986
|
+
* Maximum time in milliseconds that event property collection can take before it is considered a failure.
|
|
36987
|
+
* If collection fails more than 3 times consecutively, event property collection will be disabled completely.
|
|
36988
|
+
*
|
|
36989
|
+
* @access public
|
|
36990
|
+
* @category Config/Core
|
|
36991
|
+
* @name eventPropertyTimeout
|
|
36992
|
+
* @default 50
|
|
36993
|
+
* @type {number}
|
|
36994
|
+
*/
|
|
36995
|
+
configReader.addOption(EVENT_PROPERTY_TIMEOUT, [configReader.sources.SNIPPET_SRC, configReader.sources.PENDO_CONFIG_SRC], 50);
|
|
36996
|
+
collectionThreshold = configReader.get(EVENT_PROPERTY_TIMEOUT);
|
|
36868
36997
|
globalPendo.getEventPropertyTarget = getEventPropertyTarget;
|
|
36869
36998
|
globalPendo.previewEventProperty = collectEventProperty;
|
|
36870
36999
|
pluginAPI.Events.onClickCaptured.off(handleClickCaptured);
|
|
36871
37000
|
pluginAPI.Events.onClickCaptured.on(handleClickCaptured);
|
|
36872
37001
|
pluginAPI.Events.ready.on(addPageEventProperties);
|
|
37002
|
+
pluginAPI.Events.deliverablesLoaded.on(resetCepFailureCount);
|
|
36873
37003
|
}
|
|
36874
37004
|
function teardown() {
|
|
36875
37005
|
pluginAPI.Events.onClickCaptured.off(handleClickCaptured);
|
|
36876
37006
|
pluginAPI.Events.ready.off(addPageEventProperties);
|
|
37007
|
+
pluginAPI.Events.deliverablesLoaded.off(resetCepFailureCount);
|
|
36877
37008
|
removePageEventProperties();
|
|
36878
37009
|
pepFailureCount = 0;
|
|
36879
37010
|
cepFailureCount = 0;
|
|
36880
37011
|
}
|
|
37012
|
+
function resetCepFailureCount() {
|
|
37013
|
+
cepFailureCount = 0;
|
|
37014
|
+
}
|
|
36881
37015
|
function getRuleTesterImpl(matchParents, proxyFn) {
|
|
36882
37016
|
if (matchParents) {
|
|
36883
37017
|
return function (elem, rule) {
|
|
@@ -36946,7 +37080,8 @@ const EventProperties = (function () {
|
|
|
36946
37080
|
// Check to see if the target matches any of the feature rules
|
|
36947
37081
|
// or shortcircuit if too much time has elapsed
|
|
36948
37082
|
var ep;
|
|
36949
|
-
|
|
37083
|
+
var epIndex;
|
|
37084
|
+
for (epIndex = 0; epIndex < pageEventProperties.length && getNow() - startTime < eventPropertyCollectionThreshold; epIndex++) {
|
|
36950
37085
|
ep = pageEventProperties[epIndex];
|
|
36951
37086
|
if (!ep.name) {
|
|
36952
37087
|
return;
|
|
@@ -36958,14 +37093,20 @@ const EventProperties = (function () {
|
|
|
36958
37093
|
}
|
|
36959
37094
|
var collectionOverheadInMs = getNow() - startTime;
|
|
36960
37095
|
if (collectionOverheadInMs > eventPropertyCollectionThreshold) {
|
|
36961
|
-
logEventPropertyTimeoutMessage(eventPropertyCollectionThreshold, ep);
|
|
36962
37096
|
pepFailureCount++;
|
|
37097
|
+
logEventPropertyTimeoutMessage({
|
|
37098
|
+
threshold: eventPropertyCollectionThreshold,
|
|
37099
|
+
name: ep.name,
|
|
37100
|
+
elapsedTime: collectionOverheadInMs,
|
|
37101
|
+
failureCount: pepFailureCount,
|
|
37102
|
+
index: epIndex,
|
|
37103
|
+
length: pageEventProperties.length
|
|
37104
|
+
});
|
|
36963
37105
|
}
|
|
36964
37106
|
else {
|
|
36965
37107
|
pepFailureCount = 0;
|
|
36966
37108
|
}
|
|
36967
37109
|
if (pepFailureCount >= MAX_CONSECUTIVE_FAILURES) {
|
|
36968
|
-
logEventPropertyDisabledMessage(eventPropertyCollectionThreshold);
|
|
36969
37110
|
pageEventPropertiesTimeout = true;
|
|
36970
37111
|
}
|
|
36971
37112
|
return result;
|
|
@@ -36978,7 +37119,9 @@ const EventProperties = (function () {
|
|
|
36978
37119
|
// Check to see if the target matches any of the feature rules
|
|
36979
37120
|
// or shortcircuit if too much time has elapsed
|
|
36980
37121
|
var ep;
|
|
36981
|
-
|
|
37122
|
+
var epIndex;
|
|
37123
|
+
var len = globalPendo.eventProperties.length;
|
|
37124
|
+
for (epIndex = 0; epIndex < len && getNow() - startTime < eventPropertyCollectionThreshold; epIndex++) {
|
|
36982
37125
|
ep = globalPendo.eventProperties[epIndex];
|
|
36983
37126
|
var match = globalPendo._.any(ep.featureRules, function (rule) {
|
|
36984
37127
|
try {
|
|
@@ -37005,7 +37148,6 @@ const EventProperties = (function () {
|
|
|
37005
37148
|
// Naming matches event property name restrictions enforced by the backend.
|
|
37006
37149
|
var collectionOverheadInMs = getNow() - startTime;
|
|
37007
37150
|
if (collectionOverheadInMs > eventPropertyCollectionThreshold) {
|
|
37008
|
-
cepFailureCount++;
|
|
37009
37151
|
if (matchParents && elemProxyFn === globalPendo._.identity && globalPendo._.isFunction(globalPendo.getText)) {
|
|
37010
37152
|
globalPendo.log('switching event property collection to fast text implementation');
|
|
37011
37153
|
// Try again where textContent has been replaced with the faster (but limited) getText implementation
|
|
@@ -37017,10 +37159,17 @@ const EventProperties = (function () {
|
|
|
37017
37159
|
return createFeatureEventPropertyMap(target, eventPropertyCollectionThreshold);
|
|
37018
37160
|
}
|
|
37019
37161
|
else {
|
|
37020
|
-
|
|
37162
|
+
cepFailureCount++;
|
|
37163
|
+
logEventPropertyTimeoutMessage({
|
|
37164
|
+
threshold: eventPropertyCollectionThreshold,
|
|
37165
|
+
featureId: ep.featureId,
|
|
37166
|
+
elapsedTime: collectionOverheadInMs,
|
|
37167
|
+
failureCount: cepFailureCount,
|
|
37168
|
+
index: epIndex,
|
|
37169
|
+
length: len
|
|
37170
|
+
});
|
|
37021
37171
|
}
|
|
37022
37172
|
if (cepFailureCount >= MAX_CONSECUTIVE_FAILURES) {
|
|
37023
|
-
logEventPropertyDisabledMessage(eventPropertyCollectionThreshold);
|
|
37024
37173
|
globalPendo.eventProperties = [];
|
|
37025
37174
|
}
|
|
37026
37175
|
}
|
|
@@ -37029,18 +37178,11 @@ const EventProperties = (function () {
|
|
|
37029
37178
|
}
|
|
37030
37179
|
return result;
|
|
37031
37180
|
}
|
|
37032
|
-
function
|
|
37033
|
-
|
|
37034
|
-
|
|
37035
|
-
|
|
37036
|
-
|
|
37037
|
-
function logEventPropertyTimeoutMessage(eventPropertyCollectionThreshold, ep) {
|
|
37038
|
-
var logMessage = 'ERROR event property collection exceeded time limit.';
|
|
37039
|
-
if (ep.featureId) {
|
|
37040
|
-
logMessage += '\n For feature with id: ' + ep.featureId;
|
|
37041
|
-
}
|
|
37042
|
-
else {
|
|
37043
|
-
logMessage += '\n For page event with name: ' + ep.name;
|
|
37181
|
+
function logEventPropertyTimeoutMessage({ threshold, featureId, name, elapsedTime, failureCount, index, length }) {
|
|
37182
|
+
var logMessage = `ERROR ${featureId ? 'click' : 'page'} event property collection timeout (${featureId || name}).`;
|
|
37183
|
+
logMessage += ` ${elapsedTime}ms/${threshold}ms, ${index}/${length} properties, ${failureCount}/${MAX_CONSECUTIVE_FAILURES} failures`;
|
|
37184
|
+
if (failureCount >= MAX_CONSECUTIVE_FAILURES) {
|
|
37185
|
+
logMessage += ', collection disabled.';
|
|
37044
37186
|
}
|
|
37045
37187
|
pluginAPI.log.critical(logMessage);
|
|
37046
37188
|
}
|
|
@@ -55129,6 +55271,7 @@ var ConfigReader = (function () {
|
|
|
55129
55271
|
*/
|
|
55130
55272
|
addOption('additionalApiKeys', [PENDO_CONFIG_SRC, SNIPPET_SRC]);
|
|
55131
55273
|
addOption('allowedOriginServers');
|
|
55274
|
+
addOption('allowedOriginServerHashes');
|
|
55132
55275
|
addOption('allowMixedApiKeyFrames', [SNIPPET_SRC, PENDO_CONFIG_SRC], true);
|
|
55133
55276
|
/**
|
|
55134
55277
|
* A function that returns either an array of strings or an object to decorate the url for events.
|