@pendo/agent 2.346.0 → 2.348.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 +8 -7
- package/dist/pendo.module.js +185 -94
- package/dist/pendo.module.min.js +8 -8
- package/dist/servers.json +8 -8
- package/package.json +1 -1
package/dist/dom.esm.js
CHANGED
|
@@ -6579,9 +6579,9 @@ var ConfigReader = (function () {
|
|
|
6579
6579
|
*/
|
|
6580
6580
|
addOption('selfHostedWebSDKUrl', [SNIPPET_SRC, PENDO_CONFIG_SRC], undefined, undefined, ['selfHostedAgentUrl']);
|
|
6581
6581
|
/**
|
|
6582
|
-
* If this option is set to true, event data
|
|
6583
|
-
* of first trying to use GET requests.
|
|
6584
|
-
* is transmitted.
|
|
6582
|
+
* If this option is set to true, event data, guide requests, and segment flag requests will only be
|
|
6583
|
+
* transmitted using requests of type POST instead of first trying to use GET requests. For event data, this
|
|
6584
|
+
* can result in fewer requests being sent each time that event data is transmitted.
|
|
6585
6585
|
*
|
|
6586
6586
|
* @access public
|
|
6587
6587
|
* @category Config/Core
|
|
@@ -7555,7 +7555,7 @@ function applyMatrix2dRect(matrix2d, rect) {
|
|
|
7555
7555
|
return transformedRect;
|
|
7556
7556
|
}
|
|
7557
7557
|
|
|
7558
|
-
var VERSION = '2.
|
|
7558
|
+
var VERSION = '2.348.0_';
|
|
7559
7559
|
|
|
7560
7560
|
var decodeURIComponent = _.isFunction(globalScope.decodeURIComponent) ? globalScope.decodeURIComponent : _.identity;
|
|
7561
7561
|
|
|
@@ -7915,13 +7915,13 @@ var agentStorage = (function () {
|
|
|
7915
7915
|
resetCache(storageAvailable);
|
|
7916
7916
|
if (storageIsDisabled()) {
|
|
7917
7917
|
inMemoryStorage[key] = ttlWrite(val, duration);
|
|
7918
|
-
return;
|
|
7918
|
+
return true;
|
|
7919
7919
|
}
|
|
7920
7920
|
if (shouldUseLocalStorage(keyLocalStorageOnly)) {
|
|
7921
7921
|
if (storageAvailable('localStorage')) {
|
|
7922
7922
|
try {
|
|
7923
7923
|
localStorage.setItem(key, ttlWrite(val, duration));
|
|
7924
|
-
return;
|
|
7924
|
+
return true;
|
|
7925
7925
|
}
|
|
7926
7926
|
catch (e) { }
|
|
7927
7927
|
}
|
|
@@ -7931,11 +7931,12 @@ var agentStorage = (function () {
|
|
|
7931
7931
|
if (!isPlain)
|
|
7932
7932
|
duration = duration || DEFAULT_EXPIRE_LEN;
|
|
7933
7933
|
setCookie(key, val, duration, isSecure);
|
|
7934
|
-
return;
|
|
7934
|
+
return true;
|
|
7935
7935
|
}
|
|
7936
7936
|
catch (e) { }
|
|
7937
7937
|
}
|
|
7938
7938
|
inMemoryStorage[key] = ttlWrite(val, duration);
|
|
7939
|
+
return false;
|
|
7939
7940
|
}
|
|
7940
7941
|
function ttlWrite(value, duration) {
|
|
7941
7942
|
if (duration === null) {
|
package/dist/pendo.module.js
CHANGED
|
@@ -3271,9 +3271,9 @@ var ConfigReader = (function () {
|
|
|
3271
3271
|
*/
|
|
3272
3272
|
addOption('selfHostedWebSDKUrl', [SNIPPET_SRC, PENDO_CONFIG_SRC], undefined, undefined, ['selfHostedAgentUrl']);
|
|
3273
3273
|
/**
|
|
3274
|
-
* If this option is set to true, event data
|
|
3275
|
-
* of first trying to use GET requests.
|
|
3276
|
-
* is transmitted.
|
|
3274
|
+
* If this option is set to true, event data, guide requests, and segment flag requests will only be
|
|
3275
|
+
* transmitted using requests of type POST instead of first trying to use GET requests. For event data, this
|
|
3276
|
+
* can result in fewer requests being sent each time that event data is transmitted.
|
|
3277
3277
|
*
|
|
3278
3278
|
* @access public
|
|
3279
3279
|
* @category Config/Core
|
|
@@ -4138,8 +4138,8 @@ let SERVER = '';
|
|
|
4138
4138
|
let ASSET_HOST = '';
|
|
4139
4139
|
let ASSET_PATH = '';
|
|
4140
4140
|
let DESIGNER_SERVER = '';
|
|
4141
|
-
let VERSION = '2.
|
|
4142
|
-
let PACKAGE_VERSION = '2.
|
|
4141
|
+
let VERSION = '2.348.0_';
|
|
4142
|
+
let PACKAGE_VERSION = '2.348.0';
|
|
4143
4143
|
let LOADER = 'xhr';
|
|
4144
4144
|
/* eslint-enable web-sdk-eslint-rules/no-gulp-env-references */
|
|
4145
4145
|
/**
|
|
@@ -5133,13 +5133,13 @@ var agentStorage = (function () {
|
|
|
5133
5133
|
resetCache(storageAvailable);
|
|
5134
5134
|
if (storageIsDisabled()) {
|
|
5135
5135
|
inMemoryStorage[key] = ttlWrite(val, duration);
|
|
5136
|
-
return;
|
|
5136
|
+
return true;
|
|
5137
5137
|
}
|
|
5138
5138
|
if (shouldUseLocalStorage(keyLocalStorageOnly)) {
|
|
5139
5139
|
if (storageAvailable('localStorage')) {
|
|
5140
5140
|
try {
|
|
5141
5141
|
localStorage.setItem(key, ttlWrite(val, duration));
|
|
5142
|
-
return;
|
|
5142
|
+
return true;
|
|
5143
5143
|
}
|
|
5144
5144
|
catch (e) { }
|
|
5145
5145
|
}
|
|
@@ -5149,11 +5149,12 @@ var agentStorage = (function () {
|
|
|
5149
5149
|
if (!isPlain)
|
|
5150
5150
|
duration = duration || DEFAULT_EXPIRE_LEN;
|
|
5151
5151
|
setCookie(key, val, duration, isSecure);
|
|
5152
|
-
return;
|
|
5152
|
+
return true;
|
|
5153
5153
|
}
|
|
5154
5154
|
catch (e) { }
|
|
5155
5155
|
}
|
|
5156
5156
|
inMemoryStorage[key] = ttlWrite(val, duration);
|
|
5157
|
+
return false;
|
|
5157
5158
|
}
|
|
5158
5159
|
function ttlWrite(value, duration) {
|
|
5159
5160
|
if (duration === null) {
|
|
@@ -12995,6 +12996,23 @@ function migrateLegacyCookieEvents(events) {
|
|
|
12995
12996
|
clearCookie(getPendoCookieKey(UNSENT_EVENTS_KEY));
|
|
12996
12997
|
}
|
|
12997
12998
|
}
|
|
12999
|
+
// the quota error doesn't say how much space is left, so halving keeps the
|
|
13000
|
+
// number of retries during pagehide small
|
|
13001
|
+
function dropOldestHalf(events) {
|
|
13002
|
+
const entries = [];
|
|
13003
|
+
_.each(events, (requests, key) => {
|
|
13004
|
+
_.each(requests, (request) => {
|
|
13005
|
+
entries.push({ key, request });
|
|
13006
|
+
});
|
|
13007
|
+
});
|
|
13008
|
+
const newest = _.sortBy(entries, (entry) => entry.request.ts).slice(Math.ceil(entries.length / 2));
|
|
13009
|
+
const remaining = {};
|
|
13010
|
+
_.each(newest, (entry) => {
|
|
13011
|
+
remaining[entry.key] = remaining[entry.key] || [];
|
|
13012
|
+
remaining[entry.key].push(entry.request);
|
|
13013
|
+
});
|
|
13014
|
+
return remaining;
|
|
13015
|
+
}
|
|
12998
13016
|
class LocalStorageEventBuffer {
|
|
12999
13017
|
constructor() {
|
|
13000
13018
|
this.events = {};
|
|
@@ -13039,12 +13057,14 @@ class LocalStorageEventBuffer {
|
|
|
13039
13057
|
storage.clear(UNSENT_EVENTS_KEY);
|
|
13040
13058
|
}
|
|
13041
13059
|
write(storage) {
|
|
13042
|
-
|
|
13043
|
-
|
|
13044
|
-
|
|
13045
|
-
|
|
13046
|
-
|
|
13060
|
+
let events = this.events;
|
|
13061
|
+
while (_.size(events) > 0) {
|
|
13062
|
+
if (storage.write(UNSENT_EVENTS_KEY, JSON.stringify(events), UNSENT_EVENTS_MAX_AGE)) {
|
|
13063
|
+
return;
|
|
13064
|
+
}
|
|
13065
|
+
events = dropOldestHalf(events);
|
|
13047
13066
|
}
|
|
13067
|
+
storage.clear(UNSENT_EVENTS_KEY);
|
|
13048
13068
|
}
|
|
13049
13069
|
}
|
|
13050
13070
|
var localStorageEventBuffer = new LocalStorageEventBuffer();
|
|
@@ -13132,7 +13152,7 @@ function isDebuggingEnabled(asBoolean = true) {
|
|
|
13132
13152
|
}
|
|
13133
13153
|
}
|
|
13134
13154
|
|
|
13135
|
-
const
|
|
13155
|
+
const PERFORMANCE_COLLECT_INTERVAL = 1000 * 60 * 10; // 10 minutes
|
|
13136
13156
|
class PerformanceMonitor {
|
|
13137
13157
|
constructor() {
|
|
13138
13158
|
this._isPerformanceApiAvailable = this._checkPerformanceApi();
|
|
@@ -13140,6 +13160,8 @@ class PerformanceMonitor {
|
|
|
13140
13160
|
this._measuringPerformance = false;
|
|
13141
13161
|
this._debugging = false;
|
|
13142
13162
|
this._setDebuggingBound = _.bind(this._setDebugging, this);
|
|
13163
|
+
this._sendBound = _.bind(this.send, this);
|
|
13164
|
+
this._totals = {};
|
|
13143
13165
|
this.marks = new Set();
|
|
13144
13166
|
this.measures = new Set();
|
|
13145
13167
|
}
|
|
@@ -13150,12 +13172,13 @@ class PerformanceMonitor {
|
|
|
13150
13172
|
this._markPerformance(INITIALIZE);
|
|
13151
13173
|
this._setDebugging();
|
|
13152
13174
|
Events.debuggerLaunched.on(this._setDebuggingBound);
|
|
13175
|
+
Events.appUnloaded.on(this._sendBound);
|
|
13153
13176
|
const shouldSend = Math.random() * 100 < ConfigReader.get('performanceMetricsSampleRate');
|
|
13154
13177
|
this._setSending(shouldSend);
|
|
13155
13178
|
// interval always runs to periodically free memory used by performance api
|
|
13156
13179
|
this.interval = setInterval(() => {
|
|
13157
|
-
this.
|
|
13158
|
-
},
|
|
13180
|
+
this._collect();
|
|
13181
|
+
}, PERFORMANCE_COLLECT_INTERVAL);
|
|
13159
13182
|
return () => {
|
|
13160
13183
|
this.teardown();
|
|
13161
13184
|
};
|
|
@@ -13166,6 +13189,7 @@ class PerformanceMonitor {
|
|
|
13166
13189
|
this._measuringPerformance = false;
|
|
13167
13190
|
this._setDebugging();
|
|
13168
13191
|
Events.debuggerLaunched.off(this._setDebuggingBound);
|
|
13192
|
+
Events.appUnloaded.off(this._sendBound);
|
|
13169
13193
|
this._clearMarksAndMeasures();
|
|
13170
13194
|
clearInterval(this.interval);
|
|
13171
13195
|
}
|
|
@@ -13185,25 +13209,41 @@ class PerformanceMonitor {
|
|
|
13185
13209
|
this._markPerformance(name, { detail });
|
|
13186
13210
|
}
|
|
13187
13211
|
send() {
|
|
13188
|
-
|
|
13189
|
-
|
|
13190
|
-
|
|
13191
|
-
|
|
13192
|
-
|
|
13193
|
-
|
|
13194
|
-
|
|
13195
|
-
|
|
13196
|
-
|
|
13197
|
-
|
|
13198
|
-
|
|
13199
|
-
|
|
13200
|
-
});
|
|
13212
|
+
// runs in the appUnloaded handler ahead of the agent's event flush, so it must not throw
|
|
13213
|
+
try {
|
|
13214
|
+
this._collect();
|
|
13215
|
+
const payload = _.map(this._totals, (value, name) => ({
|
|
13216
|
+
name,
|
|
13217
|
+
type: METRICS[name].type,
|
|
13218
|
+
value,
|
|
13219
|
+
timestamp: Date.now()
|
|
13220
|
+
}));
|
|
13221
|
+
this._totals = {};
|
|
13222
|
+
if (_.size(payload) && this._sending) {
|
|
13223
|
+
writeMetricsPOST(payload);
|
|
13201
13224
|
}
|
|
13202
|
-
|
|
13203
|
-
|
|
13204
|
-
|
|
13205
|
-
|
|
13206
|
-
|
|
13225
|
+
}
|
|
13226
|
+
catch (e) {
|
|
13227
|
+
log.debug(`Failed to send performance metrics: ${e}`);
|
|
13228
|
+
}
|
|
13229
|
+
}
|
|
13230
|
+
_collect() {
|
|
13231
|
+
if (!this._isPerformanceApiAvailable)
|
|
13232
|
+
return;
|
|
13233
|
+
try {
|
|
13234
|
+
if (!this._sending)
|
|
13235
|
+
return;
|
|
13236
|
+
_.each(METRICS, ({ name, instrument }) => {
|
|
13237
|
+
if (!instrument)
|
|
13238
|
+
return;
|
|
13239
|
+
const value = instrument(performance.getEntriesByName(name));
|
|
13240
|
+
if (value > 0) {
|
|
13241
|
+
this._totals[name] = (this._totals[name] || 0) + value;
|
|
13242
|
+
}
|
|
13243
|
+
});
|
|
13244
|
+
}
|
|
13245
|
+
finally {
|
|
13246
|
+
this._clearMarksAndMeasures();
|
|
13207
13247
|
}
|
|
13208
13248
|
}
|
|
13209
13249
|
_checkPerformanceApi() {
|
|
@@ -13451,6 +13491,9 @@ function filterSiloCapacity(options) {
|
|
|
13451
13491
|
};
|
|
13452
13492
|
}
|
|
13453
13493
|
var URL_MAX_LENGTH = 2000;
|
|
13494
|
+
function shouldLoadWithPost(url, jwtOptions) {
|
|
13495
|
+
return url.length > URL_MAX_LENGTH || !_.isEmpty(jwtOptions) || !!ConfigReader.get('sendEventsWithPostOnly');
|
|
13496
|
+
}
|
|
13454
13497
|
function shortenUrlFields(options) {
|
|
13455
13498
|
options = _.defaults(options || {}, {
|
|
13456
13499
|
fields: [],
|
|
@@ -14216,6 +14259,14 @@ var isWalkthrough = function (guide) {
|
|
|
14216
14259
|
var isForm = function (guide) {
|
|
14217
14260
|
return !!(_.get(guide, 'attributes.form'));
|
|
14218
14261
|
};
|
|
14262
|
+
// An HTML guide step's type is 'html' and it has no domJson to derive calculatedType
|
|
14263
|
+
// from, so its layout only shows up in buildingBlockLayoutType
|
|
14264
|
+
var isTooltipStep = function (step) {
|
|
14265
|
+
var tooltip = 'tooltip';
|
|
14266
|
+
return _.get(step, 'type') === tooltip ||
|
|
14267
|
+
_.get(step, 'attributes.calculatedType') === tooltip ||
|
|
14268
|
+
_.get(step, 'attributes.buildingBlockLayoutType', _.get(step, 'buildingBlockLayoutType')) === tooltip;
|
|
14269
|
+
};
|
|
14219
14270
|
function isPreviewing() {
|
|
14220
14271
|
/* global selmo */
|
|
14221
14272
|
return (typeof selmo !== 'undefined' && !!selmo.isPreviewing);
|
|
@@ -17858,6 +17909,7 @@ var FlexboxPolyfill = (function () {
|
|
|
17858
17909
|
wrapElementInMockFlexboxContainer,
|
|
17859
17910
|
getVisualElementsWrappedInFlexElements,
|
|
17860
17911
|
initializeFlexRows,
|
|
17912
|
+
initializeNativeFlexRow,
|
|
17861
17913
|
getRowWidth,
|
|
17862
17914
|
wrapFlexElementsInFlexRows,
|
|
17863
17915
|
formatFlexRows,
|
|
@@ -18219,32 +18271,26 @@ var FlexboxPolyfill = (function () {
|
|
|
18219
18271
|
var computedStyles = getComputedStyle_safe(row);
|
|
18220
18272
|
return parseInt(width, 10) - parseInt(computedStyles.paddingLeft, 10) - parseInt(computedStyles.paddingRight, 10);
|
|
18221
18273
|
}
|
|
18222
|
-
function
|
|
18223
|
-
|
|
18224
|
-
|
|
18225
|
-
|
|
18226
|
-
|
|
18227
|
-
|
|
18228
|
-
|
|
18229
|
-
|
|
18230
|
-
|
|
18231
|
-
|
|
18232
|
-
|
|
18233
|
-
|
|
18234
|
-
|
|
18235
|
-
|
|
18236
|
-
|
|
18237
|
-
|
|
18238
|
-
|
|
18239
|
-
|
|
18240
|
-
|
|
18241
|
-
|
|
18242
|
-
var flexRows = FlexboxPolyfill.wrapFlexElementsInFlexRows(flexElements, row, rowWidth);
|
|
18243
|
-
// Once we have all the pendo-mock-flexbox-element elements placed in to
|
|
18244
|
-
// pendo-mock-flexbox-row rows, loop through each pendo-mock-flexbox-row and set the
|
|
18245
|
-
// height and alignment
|
|
18246
|
-
FlexboxPolyfill.formatFlexRows(flexRows, row, justifyContent, rowVerticalAlignment, rowWidth);
|
|
18247
|
-
}
|
|
18274
|
+
function initializeNativeFlexRow(row, justifyContent, rowVerticalAlignment) {
|
|
18275
|
+
var alignments = {
|
|
18276
|
+
top: 'flex-start',
|
|
18277
|
+
center: 'center',
|
|
18278
|
+
bottom: 'flex-end'
|
|
18279
|
+
};
|
|
18280
|
+
row.style.display = 'flex';
|
|
18281
|
+
row.style.flexWrap = 'wrap';
|
|
18282
|
+
row.style.justifyContent = justifyContent;
|
|
18283
|
+
row.style.alignItems = alignments[rowVerticalAlignment] || 'flex-start';
|
|
18284
|
+
}
|
|
18285
|
+
function initializeFlexRows(row, justifyContent, rowVerticalAlignment, rowWidth) {
|
|
18286
|
+
var flexElements = getFlexboxElements(row.children);
|
|
18287
|
+
if (flexElements.length === 0)
|
|
18288
|
+
return;
|
|
18289
|
+
var flexRows = FlexboxPolyfill.wrapFlexElementsInFlexRows(flexElements, row, rowWidth);
|
|
18290
|
+
// Once we have all the pendo-mock-flexbox-element elements placed in to
|
|
18291
|
+
// pendo-mock-flexbox-row rows, loop through each pendo-mock-flexbox-row and set the
|
|
18292
|
+
// height and alignment
|
|
18293
|
+
FlexboxPolyfill.formatFlexRows(flexRows, row, justifyContent, rowVerticalAlignment, rowWidth);
|
|
18248
18294
|
}
|
|
18249
18295
|
function wrapFlexElementsInFlexRows(flexElements, row, rowWidthPreCalc) {
|
|
18250
18296
|
var rowWidth = rowWidthPreCalc || getRowWidth(row);
|
|
@@ -18324,10 +18370,17 @@ var FlexboxPolyfill = (function () {
|
|
|
18324
18370
|
function flexElement(ele, useNativeFlexbox) {
|
|
18325
18371
|
var rowsToBeFlexed = dom('[data-pendo-display-flex]', ele);
|
|
18326
18372
|
_.each(rowsToBeFlexed, function (row) {
|
|
18327
|
-
var rowWithFlexedElements = useNativeFlexbox ? row : FlexboxPolyfill.initializeFlexElements(row);
|
|
18328
18373
|
var horizontalAlignment = row.getAttribute('data-pendo-justify-content');
|
|
18329
18374
|
var rowVerticalAlignment = row.getAttribute('data-row-vertical-alignment');
|
|
18330
|
-
|
|
18375
|
+
if (useNativeFlexbox) {
|
|
18376
|
+
FlexboxPolyfill.initializeNativeFlexRow(row, horizontalAlignment, rowVerticalAlignment);
|
|
18377
|
+
return;
|
|
18378
|
+
}
|
|
18379
|
+
// Initializing flex elements can add a temporary scrollbar to a scrolling ancestor and shrink the
|
|
18380
|
+
// width of the rows. Pre-measure the row width to prevent its children from wrapping onto a new row.
|
|
18381
|
+
var rowWidth = FlexboxPolyfill.getRowWidth(row);
|
|
18382
|
+
var rowWithFlexedElements = FlexboxPolyfill.initializeFlexElements(row);
|
|
18383
|
+
FlexboxPolyfill.initializeFlexRows(rowWithFlexedElements, horizontalAlignment, rowVerticalAlignment, rowWidth);
|
|
18331
18384
|
});
|
|
18332
18385
|
}
|
|
18333
18386
|
function flexAllThings(containerId, step) {
|
|
@@ -22891,7 +22944,7 @@ function stepShowingProc(guide, step) {
|
|
|
22891
22944
|
step.checkPlacement();
|
|
22892
22945
|
return;
|
|
22893
22946
|
}
|
|
22894
|
-
var isTooltip = (step
|
|
22947
|
+
var isTooltip = isTooltipStep(step);
|
|
22895
22948
|
if (isTooltip && wouldBeVisibleAfterAutoScroll(element) && elementMatchesContainsRules) {
|
|
22896
22949
|
// the element was scrolled out of view, the guide should be invisible for now, but still "active"
|
|
22897
22950
|
return;
|
|
@@ -23693,10 +23746,9 @@ function attachP1AdvanceActions(step, guide, pendo) {
|
|
|
23693
23746
|
return;
|
|
23694
23747
|
if (isBadge(guide) && !isWalkthrough(guide))
|
|
23695
23748
|
return;
|
|
23696
|
-
|
|
23697
|
-
const htmlLayoutType = _.get(step, 'attributes.buildingBlockLayoutType', step.buildingBlockLayoutType);
|
|
23698
|
-
if (!_.contains([htmlLayoutType, step.type], 'tooltip'))
|
|
23749
|
+
if (!isTooltipStep(step))
|
|
23699
23750
|
return;
|
|
23751
|
+
const { _ } = pendo;
|
|
23700
23752
|
const advanceMethods = step.advanceMethod.split(',');
|
|
23701
23753
|
_.each(advanceMethods, (method) => {
|
|
23702
23754
|
if (method === 'element') {
|
|
@@ -23936,12 +23988,6 @@ var popoverStep = {
|
|
|
23936
23988
|
script: popoverRuntimeScript
|
|
23937
23989
|
};
|
|
23938
23990
|
|
|
23939
|
-
function isTooltip({ _ }, step) {
|
|
23940
|
-
const tooltip = 'tooltip';
|
|
23941
|
-
return _.get(step, 'attributes.calculatedType') === tooltip ||
|
|
23942
|
-
_.get(step, 'attributes.buildingBlockLayoutType', step.buildingBlockLayoutType) === tooltip ||
|
|
23943
|
-
step.type === tooltip;
|
|
23944
|
-
}
|
|
23945
23991
|
function attachScrollHandlers({ _ }, step, scrollCallback) {
|
|
23946
23992
|
const throttledScrollCallback = _.throttle(_.bind(scrollCallback, step, step), 10);
|
|
23947
23993
|
step.attachEvent(window, 'scroll', throttledScrollCallback, true);
|
|
@@ -23969,7 +24015,7 @@ function attachStepScrollHandlers(step, guide, pendo) {
|
|
|
23969
24015
|
// APP-68789
|
|
23970
24016
|
if (isPreviewing() && step.element === dom.getBody())
|
|
23971
24017
|
return;
|
|
23972
|
-
if (
|
|
24018
|
+
if (isTooltipStep(step)) {
|
|
23973
24019
|
const repositionCallback = step.domJson ? bbRepositionTooltip : p1RepositionTooltip;
|
|
23974
24020
|
attachScrollHandlers(pendo, step, _.partial(tooltipOnScroll, pendo, step, repositionCallback));
|
|
23975
24021
|
}
|
|
@@ -24668,11 +24714,17 @@ var canStepBeRendered = function (step) {
|
|
|
24668
24714
|
if (targetElem && step.elementContainsRulesList && !doesElementMatchContainsRules(targetElem, step.elementContainsRulesList)) {
|
|
24669
24715
|
return statusWriter(false, 'contains_rules');
|
|
24670
24716
|
}
|
|
24671
|
-
const
|
|
24672
|
-
if (
|
|
24673
|
-
|
|
24717
|
+
const embedConfig = _.get(step, 'guide.attributes.embedConfig');
|
|
24718
|
+
if (embedConfig && embedConfig.selector) {
|
|
24719
|
+
const embedHost = dom(embedConfig.selector)[0];
|
|
24720
|
+
if (!embedHost) {
|
|
24721
|
+
return false;
|
|
24722
|
+
}
|
|
24723
|
+
if (embedConfig.method === 'replace' && isEmbedHostReplacedByAnotherGuide(step.guide, embedHost)) {
|
|
24724
|
+
return false;
|
|
24725
|
+
}
|
|
24674
24726
|
}
|
|
24675
|
-
var isTooltip = step
|
|
24727
|
+
var isTooltip = isTooltipStep(step) || BuildingBlockTooltips.isBuildingBlockGuideRelativeToElement(step);
|
|
24676
24728
|
var isVisible = isElementVisible(elm);
|
|
24677
24729
|
if (!isTooltip) {
|
|
24678
24730
|
return statusWriter(isVisible, 'target_element');
|
|
@@ -24683,6 +24735,14 @@ var canStepBeRendered = function (step) {
|
|
|
24683
24735
|
const wouldBeVisible = wouldBeVisibleAfterAutoScroll(elm);
|
|
24684
24736
|
return statusWriter(wouldBeVisible, 'target_element_tooltip_scroll');
|
|
24685
24737
|
};
|
|
24738
|
+
function isEmbedHostReplacedByAnotherGuide(guide, embedHost) {
|
|
24739
|
+
return _.some(getActiveGuides(), function (other) {
|
|
24740
|
+
if (other === guide || !_.isFunction(other.isShown) || !other.isShown())
|
|
24741
|
+
return false;
|
|
24742
|
+
const otherEmbedConfig = _.get(other, 'attributes.embedConfig');
|
|
24743
|
+
return !!otherEmbedConfig && otherEmbedConfig.method === 'replace' && dom(otherEmbedConfig.selector)[0] === embedHost;
|
|
24744
|
+
});
|
|
24745
|
+
}
|
|
24686
24746
|
function pullContentsFromTargetElement(ele) {
|
|
24687
24747
|
var wrappedEle = dom(ele);
|
|
24688
24748
|
var eleText = wrappedEle.text() || ''; // .text() can return undefined
|
|
@@ -25195,7 +25255,7 @@ var loadGuideJs = function (apiKey, params) {
|
|
|
25195
25255
|
var url = buildBaseDataUrl(guideLoaderImpl.endpoint(), apiKey, queryString);
|
|
25196
25256
|
var jwtOptions = JWT.get();
|
|
25197
25257
|
let loadingPromise;
|
|
25198
|
-
if (url
|
|
25258
|
+
if (shouldLoadWithPost(url, jwtOptions)) {
|
|
25199
25259
|
delete queryString.jzb;
|
|
25200
25260
|
url = buildBaseDataUrl('guide.json', apiKey, queryString);
|
|
25201
25261
|
var payload = _.extend({ events: jzb }, jwtOptions);
|
|
@@ -29711,10 +29771,6 @@ const PluginAPI = {
|
|
|
29711
29771
|
removeGlobalScript: GuideRuntime.removeGlobalScript
|
|
29712
29772
|
},
|
|
29713
29773
|
GuideActivity,
|
|
29714
|
-
GuideEvents: {
|
|
29715
|
-
stageGuideEvent,
|
|
29716
|
-
createGuideEvent
|
|
29717
|
-
},
|
|
29718
29774
|
GuideLoop: {
|
|
29719
29775
|
addUpdatePhase,
|
|
29720
29776
|
removeUpdatePhase
|
|
@@ -29744,7 +29800,8 @@ const PluginAPI = {
|
|
|
29744
29800
|
transmit: {
|
|
29745
29801
|
buildBaseDataUrl,
|
|
29746
29802
|
fetchKeepalive,
|
|
29747
|
-
sendBeacon
|
|
29803
|
+
sendBeacon,
|
|
29804
|
+
shouldLoadWithPost
|
|
29748
29805
|
},
|
|
29749
29806
|
log,
|
|
29750
29807
|
NetworkRequest,
|
|
@@ -29919,6 +29976,19 @@ function initIdentityEvents() {
|
|
|
29919
29976
|
};
|
|
29920
29977
|
}
|
|
29921
29978
|
|
|
29979
|
+
/**
|
|
29980
|
+
* The cookie consent tier, or tiers, the visitor has already agreed to. Each tier is the id of a cookie consent
|
|
29981
|
+
* level configured for your subscription, and determines what data the web SDK can collect: visitor identity,
|
|
29982
|
+
* analytics events, guides, and session replay. If not set, the web SDK runs without any consent restrictions.
|
|
29983
|
+
* Use `pendo.updateCookieConsent` to change consent after initialization. Read more about
|
|
29984
|
+
* [Cookie Consent Levels](/cookies/consent-levels).
|
|
29985
|
+
*
|
|
29986
|
+
* @access public
|
|
29987
|
+
* @category Config/Core
|
|
29988
|
+
* @name cookieConsentTiers
|
|
29989
|
+
* @default undefined
|
|
29990
|
+
* @type {string | string[]}
|
|
29991
|
+
*/
|
|
29922
29992
|
const CONSENT_TIERS = 'cookieConsentTiers';
|
|
29923
29993
|
function applyCookieConsent(tiers, identity) {
|
|
29924
29994
|
rememberConsentTiers(tiers);
|
|
@@ -29940,18 +30010,21 @@ function isCurrentCookieConsent(tiers) {
|
|
|
29940
30010
|
}
|
|
29941
30011
|
/**
|
|
29942
30012
|
* Enforces the cookie consent policy a visitor has agreed to. The policy is defined by the subscription's cookie consent configuration,
|
|
29943
|
-
* and is used to determine
|
|
30013
|
+
* and is used to determine what data the web SDK can collect. The new tiers replace any previously consented tiers,
|
|
30014
|
+
* including those passed to `pendo.initialize` as `cookieConsentTiers`, and are shared with other frames running the web SDK for the same application.
|
|
29944
30015
|
*
|
|
29945
30016
|
* A visitor who was not being tracked has no identity for the web SDK to resume, so pass one in
|
|
29946
30017
|
* `identity` when the new tiers start allowing identity. It is ignored otherwise.
|
|
29947
30018
|
*
|
|
30019
|
+
* Read more about [Cookie Consent Levels](/cookies/consent-levels).
|
|
30020
|
+
*
|
|
29948
30021
|
* @access public
|
|
29949
30022
|
* @category Core
|
|
29950
30023
|
* @param {string | string[]} tiers tier or tiers the visitor consented to
|
|
29951
30024
|
* @param {object} [identity] visitor and account to identify, in the same shape as
|
|
29952
30025
|
* `pendo.updateOptions` -- applied only when consent moves a do-not-track visitor to a tier
|
|
29953
30026
|
* that permits identity
|
|
29954
|
-
* @returns {object}
|
|
30027
|
+
* @returns {object} what data is now collected -- `guides` and `identity` are
|
|
29955
30028
|
* booleans (identity disabled means DNT), `textCollection` is `none`/`whitelist`/`all`,
|
|
29956
30029
|
* `analytics` and `guideAnalytics` are each an array of allowed event types
|
|
29957
30030
|
* @example
|
|
@@ -33923,10 +33996,12 @@ function Poll(guide) {
|
|
|
33923
33996
|
_.each(responses, function (response, i) {
|
|
33924
33997
|
var curPoll = getPoll(response.pollId, guide);
|
|
33925
33998
|
var evt = createGuideEvent('pollResponse', step.guideId, step.id, get_visitor_id(), undefined, guide.language);
|
|
33999
|
+
// A behavior that replaces show() outright (HTML guides) drops the after('show')
|
|
34000
|
+
// hook above, so fall back to when the step was last seen.
|
|
33926
34001
|
_.extend(evt.props, {
|
|
33927
34002
|
poll_id: response.pollId,
|
|
33928
34003
|
poll_response: response.value,
|
|
33929
|
-
duration: (new Date().getTime() - shownTime)
|
|
34004
|
+
duration: (new Date().getTime() - (shownTime || step.lastSeenAt))
|
|
33930
34005
|
}, options);
|
|
33931
34006
|
if (curPoll &&
|
|
33932
34007
|
curPoll.attributes &&
|
|
@@ -33985,7 +34060,11 @@ var GuideDisplay = (function () {
|
|
|
33985
34060
|
return false;
|
|
33986
34061
|
}
|
|
33987
34062
|
step.lock();
|
|
33988
|
-
|
|
34063
|
+
// Prefer the step's own fetchContent so a plugin-defined step (e.g. HTML
|
|
34064
|
+
// guides) can supply its content; for building-block steps it is
|
|
34065
|
+
// AsyncContent.fetchContent anyway
|
|
34066
|
+
var contentPromise = _.isFunction(step.fetchContent) ? step.fetchContent() : AsyncContent.fetchContent(step);
|
|
34067
|
+
return contentPromise.then(function () {
|
|
33989
34068
|
if (step.type !== 'whatsnew' && !step.isShown()) {
|
|
33990
34069
|
return false;
|
|
33991
34070
|
}
|
|
@@ -37238,7 +37317,11 @@ var Branding = (function () {
|
|
|
37238
37317
|
return;
|
|
37239
37318
|
var guide = pendo.findGuideById(props.guide_id);
|
|
37240
37319
|
var guideContainer = guide.steps[0].guideElement[0].lastElementChild;
|
|
37241
|
-
var verticalAlignment = guideContainer.dataset.verticalAlignment;
|
|
37320
|
+
var verticalAlignment = guideContainer && guideContainer.dataset.verticalAlignment;
|
|
37321
|
+
// Only Visual Design Studio containers carry the alignment the badge is placed by;
|
|
37322
|
+
// an HTML guide's container has none.
|
|
37323
|
+
if (!verticalAlignment)
|
|
37324
|
+
return;
|
|
37242
37325
|
var isBottomAligned = verticalAlignment.indexOf('Bottom') > -1;
|
|
37243
37326
|
var isSetWidth = guideContainer.style.width !== '';
|
|
37244
37327
|
var link = document.createElement('a');
|
|
@@ -41172,7 +41255,7 @@ var buildLauncherItem = function (guide) {
|
|
|
41172
41255
|
dom(guideContainer).attr('id', 'launcher-' + guide.id);
|
|
41173
41256
|
var guideLink = document.createElement('a');
|
|
41174
41257
|
guideLink.href = '#';
|
|
41175
|
-
guideLink.
|
|
41258
|
+
guideLink.appendChild(document.createTextNode(guide.name));
|
|
41176
41259
|
guideContainer.appendChild(guideLink);
|
|
41177
41260
|
return guideContainer;
|
|
41178
41261
|
};
|
|
@@ -41527,8 +41610,9 @@ var P1GuidePlugin = (function () {
|
|
|
41527
41610
|
// Adds a close button to the guide
|
|
41528
41611
|
function CloseButton(guide) {
|
|
41529
41612
|
var step = this;
|
|
41530
|
-
// We only want to have the agent add close buttons to legacy guides, not building block
|
|
41531
|
-
|
|
41613
|
+
// We only want to have the agent add close buttons to legacy guides, not building block
|
|
41614
|
+
// inserts or HTML guides (which have no domJson either)
|
|
41615
|
+
if (step.domJson || step.domJsonpUrl || step.type === 'html')
|
|
41532
41616
|
return step;
|
|
41533
41617
|
step.after('render', function () {
|
|
41534
41618
|
if (!step.guideElement || !step.guideElement.length)
|
|
@@ -41545,7 +41629,7 @@ var P1GuidePlugin = (function () {
|
|
|
41545
41629
|
// Adds pendo credits to the guide unless disabled
|
|
41546
41630
|
function Credits() {
|
|
41547
41631
|
var step = this;
|
|
41548
|
-
if (!step.hideCredits && !step.domJson && !step.domJsonpUrl && !isForm(step.guide)) {
|
|
41632
|
+
if (!step.hideCredits && !step.domJson && !step.domJsonpUrl && step.type !== 'html' && !isForm(step.guide)) {
|
|
41549
41633
|
step.after('render', function () {
|
|
41550
41634
|
_addCredits(step.guideElement[0]);
|
|
41551
41635
|
});
|
|
@@ -41858,7 +41942,7 @@ function SegmentFlags() {
|
|
|
41858
41942
|
const jwtOptions = pluginApi.agent.getJwtInfoCopy();
|
|
41859
41943
|
let payload;
|
|
41860
41944
|
try {
|
|
41861
|
-
if (
|
|
41945
|
+
if (pluginApi.transmit.shouldLoadWithPost(url, jwtOptions)) {
|
|
41862
41946
|
delete queryString.jzb;
|
|
41863
41947
|
url = pluginApi.transmit.buildBaseDataUrl('segmentflag.json', globalPendo.apiKey, queryString);
|
|
41864
41948
|
payload = globalPendo._.extend({ events: jzb }, jwtOptions);
|
|
@@ -48091,7 +48175,7 @@ function serializeNodeWithId(n, options) {
|
|
|
48091
48175
|
if (parent && isShadowRoot(parent) && isNativeShadowDom(parent)) {
|
|
48092
48176
|
serializedNode.isShadow = true;
|
|
48093
48177
|
}
|
|
48094
|
-
if (serializedNode.type === NodeType.Element && serializedNode.tagName === "iframe") {
|
|
48178
|
+
if (serializedNode.type === NodeType.Element && serializedNode.tagName === "iframe" && !_isBlockedElement(n, blockClass, blockSelector)) {
|
|
48095
48179
|
onceIframeLoaded(
|
|
48096
48180
|
n,
|
|
48097
48181
|
() => {
|
|
@@ -50241,11 +50325,15 @@ class IframeManager {
|
|
|
50241
50325
|
__publicField(this, "pageHideListener");
|
|
50242
50326
|
__publicField(this, "stylesheetManager");
|
|
50243
50327
|
__publicField(this, "recordCrossOriginIframes");
|
|
50328
|
+
__publicField(this, "blockClass");
|
|
50329
|
+
__publicField(this, "blockSelector");
|
|
50244
50330
|
this.mutationCb = options.mutationCb;
|
|
50245
50331
|
this.wrappedEmit = options.wrappedEmit;
|
|
50246
50332
|
this.takeFullSnapshot = options.takeFullSnapshot;
|
|
50247
50333
|
this.stylesheetManager = options.stylesheetManager;
|
|
50248
50334
|
this.recordCrossOriginIframes = options.recordCrossOriginIframes;
|
|
50335
|
+
this.blockClass = options.blockClass;
|
|
50336
|
+
this.blockSelector = options.blockSelector;
|
|
50249
50337
|
this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(
|
|
50250
50338
|
this.stylesheetManager.styleMirror.generateId.bind(
|
|
50251
50339
|
this.stylesheetManager.styleMirror
|
|
@@ -50260,6 +50348,7 @@ class IframeManager {
|
|
|
50260
50348
|
this.takeFullSnapshot = takeFullSnapshot2;
|
|
50261
50349
|
}
|
|
50262
50350
|
addIframe(iframeEl) {
|
|
50351
|
+
if (isBlocked(iframeEl, this.blockClass, this.blockSelector, false)) return;
|
|
50263
50352
|
this.iframes.set(iframeEl, true);
|
|
50264
50353
|
if (iframeEl.contentWindow)
|
|
50265
50354
|
this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);
|
|
@@ -51384,6 +51473,8 @@ function record(options = {}) {
|
|
|
51384
51473
|
mutationCb: wrappedMutationEmit,
|
|
51385
51474
|
stylesheetManager,
|
|
51386
51475
|
recordCrossOriginIframes,
|
|
51476
|
+
blockClass,
|
|
51477
|
+
blockSelector,
|
|
51387
51478
|
wrappedEmit,
|
|
51388
51479
|
takeFullSnapshot
|
|
51389
51480
|
});
|