@pendo/agent 2.346.0 → 2.347.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 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 will only be transmitted using requests of type POST instead
6583
- * of first trying to use GET requests. This can result in fewer requests being sent each time that event data
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.346.0_';
7558
+ var VERSION = '2.347.0_';
7559
7559
 
7560
7560
  var decodeURIComponent = _.isFunction(globalScope.decodeURIComponent) ? globalScope.decodeURIComponent : _.identity;
7561
7561
 
@@ -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 will only be transmitted using requests of type POST instead
3275
- * of first trying to use GET requests. This can result in fewer requests being sent each time that event data
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.346.0_';
4142
- let PACKAGE_VERSION = '2.346.0';
4141
+ let VERSION = '2.347.0_';
4142
+ let PACKAGE_VERSION = '2.347.0';
4143
4143
  let LOADER = 'xhr';
4144
4144
  /* eslint-enable web-sdk-eslint-rules/no-gulp-env-references */
4145
4145
  /**
@@ -13132,7 +13132,7 @@ function isDebuggingEnabled(asBoolean = true) {
13132
13132
  }
13133
13133
  }
13134
13134
 
13135
- const PERFORMANCE_SEND_INTERVAL = 1000 * 60 * 10; // 10 minutes
13135
+ const PERFORMANCE_COLLECT_INTERVAL = 1000 * 60 * 10; // 10 minutes
13136
13136
  class PerformanceMonitor {
13137
13137
  constructor() {
13138
13138
  this._isPerformanceApiAvailable = this._checkPerformanceApi();
@@ -13140,6 +13140,8 @@ class PerformanceMonitor {
13140
13140
  this._measuringPerformance = false;
13141
13141
  this._debugging = false;
13142
13142
  this._setDebuggingBound = _.bind(this._setDebugging, this);
13143
+ this._sendBound = _.bind(this.send, this);
13144
+ this._totals = {};
13143
13145
  this.marks = new Set();
13144
13146
  this.measures = new Set();
13145
13147
  }
@@ -13150,12 +13152,13 @@ class PerformanceMonitor {
13150
13152
  this._markPerformance(INITIALIZE);
13151
13153
  this._setDebugging();
13152
13154
  Events.debuggerLaunched.on(this._setDebuggingBound);
13155
+ Events.appUnloaded.on(this._sendBound);
13153
13156
  const shouldSend = Math.random() * 100 < ConfigReader.get('performanceMetricsSampleRate');
13154
13157
  this._setSending(shouldSend);
13155
13158
  // interval always runs to periodically free memory used by performance api
13156
13159
  this.interval = setInterval(() => {
13157
- this.send(); // includes call to _clearMarksAndMeasures()
13158
- }, PERFORMANCE_SEND_INTERVAL);
13160
+ this._collect();
13161
+ }, PERFORMANCE_COLLECT_INTERVAL);
13159
13162
  return () => {
13160
13163
  this.teardown();
13161
13164
  };
@@ -13166,6 +13169,7 @@ class PerformanceMonitor {
13166
13169
  this._measuringPerformance = false;
13167
13170
  this._setDebugging();
13168
13171
  Events.debuggerLaunched.off(this._setDebuggingBound);
13172
+ Events.appUnloaded.off(this._sendBound);
13169
13173
  this._clearMarksAndMeasures();
13170
13174
  clearInterval(this.interval);
13171
13175
  }
@@ -13185,25 +13189,41 @@ class PerformanceMonitor {
13185
13189
  this._markPerformance(name, { detail });
13186
13190
  }
13187
13191
  send() {
13188
- const payload = _.reduce(METRICS, (acc, metric) => {
13189
- const { name, type, instrument } = metric;
13190
- if (!instrument)
13191
- return acc;
13192
- const entries = performance.getEntriesByName(name);
13193
- const value = instrument(entries);
13194
- if (value > 0) {
13195
- acc.push({
13196
- name,
13197
- type,
13198
- value,
13199
- timestamp: Date.now()
13200
- });
13192
+ // runs in the appUnloaded handler ahead of the agent's event flush, so it must not throw
13193
+ try {
13194
+ this._collect();
13195
+ const payload = _.map(this._totals, (value, name) => ({
13196
+ name,
13197
+ type: METRICS[name].type,
13198
+ value,
13199
+ timestamp: Date.now()
13200
+ }));
13201
+ this._totals = {};
13202
+ if (_.size(payload) && this._sending) {
13203
+ writeMetricsPOST(payload);
13201
13204
  }
13202
- return acc;
13203
- }, []);
13204
- this._clearMarksAndMeasures();
13205
- if (_.size(payload) && this._sending) {
13206
- writeMetricsPOST(payload);
13205
+ }
13206
+ catch (e) {
13207
+ log.debug(`Failed to send performance metrics: ${e}`);
13208
+ }
13209
+ }
13210
+ _collect() {
13211
+ if (!this._isPerformanceApiAvailable)
13212
+ return;
13213
+ try {
13214
+ if (!this._sending)
13215
+ return;
13216
+ _.each(METRICS, ({ name, instrument }) => {
13217
+ if (!instrument)
13218
+ return;
13219
+ const value = instrument(performance.getEntriesByName(name));
13220
+ if (value > 0) {
13221
+ this._totals[name] = (this._totals[name] || 0) + value;
13222
+ }
13223
+ });
13224
+ }
13225
+ finally {
13226
+ this._clearMarksAndMeasures();
13207
13227
  }
13208
13228
  }
13209
13229
  _checkPerformanceApi() {
@@ -13451,6 +13471,9 @@ function filterSiloCapacity(options) {
13451
13471
  };
13452
13472
  }
13453
13473
  var URL_MAX_LENGTH = 2000;
13474
+ function shouldLoadWithPost(url, jwtOptions) {
13475
+ return url.length > URL_MAX_LENGTH || !_.isEmpty(jwtOptions) || !!ConfigReader.get('sendEventsWithPostOnly');
13476
+ }
13454
13477
  function shortenUrlFields(options) {
13455
13478
  options = _.defaults(options || {}, {
13456
13479
  fields: [],
@@ -25195,7 +25218,7 @@ var loadGuideJs = function (apiKey, params) {
25195
25218
  var url = buildBaseDataUrl(guideLoaderImpl.endpoint(), apiKey, queryString);
25196
25219
  var jwtOptions = JWT.get();
25197
25220
  let loadingPromise;
25198
- if (url.length > URL_MAX_LENGTH || !_.isEmpty(jwtOptions)) {
25221
+ if (shouldLoadWithPost(url, jwtOptions)) {
25199
25222
  delete queryString.jzb;
25200
25223
  url = buildBaseDataUrl('guide.json', apiKey, queryString);
25201
25224
  var payload = _.extend({ events: jzb }, jwtOptions);
@@ -29744,7 +29767,8 @@ const PluginAPI = {
29744
29767
  transmit: {
29745
29768
  buildBaseDataUrl,
29746
29769
  fetchKeepalive,
29747
- sendBeacon
29770
+ sendBeacon,
29771
+ shouldLoadWithPost
29748
29772
  },
29749
29773
  log,
29750
29774
  NetworkRequest,
@@ -33923,10 +33947,12 @@ function Poll(guide) {
33923
33947
  _.each(responses, function (response, i) {
33924
33948
  var curPoll = getPoll(response.pollId, guide);
33925
33949
  var evt = createGuideEvent('pollResponse', step.guideId, step.id, get_visitor_id(), undefined, guide.language);
33950
+ // A behavior that replaces show() outright (HTML guides) drops the after('show')
33951
+ // hook above, so fall back to when the step was last seen.
33926
33952
  _.extend(evt.props, {
33927
33953
  poll_id: response.pollId,
33928
33954
  poll_response: response.value,
33929
- duration: (new Date().getTime() - shownTime)
33955
+ duration: (new Date().getTime() - (shownTime || step.lastSeenAt))
33930
33956
  }, options);
33931
33957
  if (curPoll &&
33932
33958
  curPoll.attributes &&
@@ -37238,7 +37264,11 @@ var Branding = (function () {
37238
37264
  return;
37239
37265
  var guide = pendo.findGuideById(props.guide_id);
37240
37266
  var guideContainer = guide.steps[0].guideElement[0].lastElementChild;
37241
- var verticalAlignment = guideContainer.dataset.verticalAlignment;
37267
+ var verticalAlignment = guideContainer && guideContainer.dataset.verticalAlignment;
37268
+ // Only Visual Design Studio containers carry the alignment the badge is placed by;
37269
+ // an HTML guide's container has none.
37270
+ if (!verticalAlignment)
37271
+ return;
37242
37272
  var isBottomAligned = verticalAlignment.indexOf('Bottom') > -1;
37243
37273
  var isSetWidth = guideContainer.style.width !== '';
37244
37274
  var link = document.createElement('a');
@@ -41172,7 +41202,7 @@ var buildLauncherItem = function (guide) {
41172
41202
  dom(guideContainer).attr('id', 'launcher-' + guide.id);
41173
41203
  var guideLink = document.createElement('a');
41174
41204
  guideLink.href = '#';
41175
- guideLink.innerHTML = guide.name;
41205
+ guideLink.appendChild(document.createTextNode(guide.name));
41176
41206
  guideContainer.appendChild(guideLink);
41177
41207
  return guideContainer;
41178
41208
  };
@@ -41858,7 +41888,7 @@ function SegmentFlags() {
41858
41888
  const jwtOptions = pluginApi.agent.getJwtInfoCopy();
41859
41889
  let payload;
41860
41890
  try {
41861
- if (url.length > pluginApi.constants.URL_MAX_LENGTH || !globalPendo._.isEmpty(jwtOptions)) {
41891
+ if (pluginApi.transmit.shouldLoadWithPost(url, jwtOptions)) {
41862
41892
  delete queryString.jzb;
41863
41893
  url = pluginApi.transmit.buildBaseDataUrl('segmentflag.json', globalPendo.apiKey, queryString);
41864
41894
  payload = globalPendo._.extend({ events: jzb }, jwtOptions);
@@ -48091,7 +48121,7 @@ function serializeNodeWithId(n, options) {
48091
48121
  if (parent && isShadowRoot(parent) && isNativeShadowDom(parent)) {
48092
48122
  serializedNode.isShadow = true;
48093
48123
  }
48094
- if (serializedNode.type === NodeType.Element && serializedNode.tagName === "iframe") {
48124
+ if (serializedNode.type === NodeType.Element && serializedNode.tagName === "iframe" && !_isBlockedElement(n, blockClass, blockSelector)) {
48095
48125
  onceIframeLoaded(
48096
48126
  n,
48097
48127
  () => {
@@ -50241,11 +50271,15 @@ class IframeManager {
50241
50271
  __publicField(this, "pageHideListener");
50242
50272
  __publicField(this, "stylesheetManager");
50243
50273
  __publicField(this, "recordCrossOriginIframes");
50274
+ __publicField(this, "blockClass");
50275
+ __publicField(this, "blockSelector");
50244
50276
  this.mutationCb = options.mutationCb;
50245
50277
  this.wrappedEmit = options.wrappedEmit;
50246
50278
  this.takeFullSnapshot = options.takeFullSnapshot;
50247
50279
  this.stylesheetManager = options.stylesheetManager;
50248
50280
  this.recordCrossOriginIframes = options.recordCrossOriginIframes;
50281
+ this.blockClass = options.blockClass;
50282
+ this.blockSelector = options.blockSelector;
50249
50283
  this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(
50250
50284
  this.stylesheetManager.styleMirror.generateId.bind(
50251
50285
  this.stylesheetManager.styleMirror
@@ -50260,6 +50294,7 @@ class IframeManager {
50260
50294
  this.takeFullSnapshot = takeFullSnapshot2;
50261
50295
  }
50262
50296
  addIframe(iframeEl) {
50297
+ if (isBlocked(iframeEl, this.blockClass, this.blockSelector, false)) return;
50263
50298
  this.iframes.set(iframeEl, true);
50264
50299
  if (iframeEl.contentWindow)
50265
50300
  this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);
@@ -51384,6 +51419,8 @@ function record(options = {}) {
51384
51419
  mutationCb: wrappedMutationEmit,
51385
51420
  stylesheetManager,
51386
51421
  recordCrossOriginIframes,
51422
+ blockClass,
51423
+ blockSelector,
51387
51424
  wrappedEmit,
51388
51425
  takeFullSnapshot
51389
51426
  });