@pendo/agent 2.287.1 → 2.288.1

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
@@ -6058,6 +6058,11 @@ var _pendoConfig = {};
6058
6058
  function getPendoConfig() {
6059
6059
  return _pendoConfig;
6060
6060
  }
6061
+ function getPendoConfigFromEnclosingScope() {
6062
+ if (typeof PendoConfig === 'undefined')
6063
+ return {};
6064
+ return PendoConfig;
6065
+ }
6061
6066
 
6062
6067
  function deepCopy(obj) {
6063
6068
  if (_.isFunction(obj) || _.isRegExp(obj)) {
@@ -7010,7 +7015,7 @@ var ConfigReader = (function () {
7010
7015
  var EXTENSION_INSTALL_TYPE = 'extension';
7011
7016
  var NATIVE_INSTALL_TYPE = 'native';
7012
7017
  function getInstallType() {
7013
- var installType = ConfigReader.get('installType');
7018
+ var installType = ConfigReader.get('installType') || getPendoConfigFromEnclosingScope().installType;
7014
7019
  return installType || NATIVE_INSTALL_TYPE;
7015
7020
  }
7016
7021
  function isExtensionAgent() {
@@ -7287,7 +7292,7 @@ function getScreenPosition(element) {
7287
7292
  };
7288
7293
  }
7289
7294
 
7290
- var VERSION = '2.287.1_';
7295
+ var VERSION = '2.288.1_';
7291
7296
 
7292
7297
  var decodeURIComponent = _.isFunction(window.decodeURIComponent) ? window.decodeURIComponent : _.identity;
7293
7298
 
@@ -3661,7 +3661,7 @@ var PROD = 'prod';
3661
3661
  var EXTENSION_INSTALL_TYPE = 'extension';
3662
3662
  var NATIVE_INSTALL_TYPE = 'native';
3663
3663
  function getInstallType() {
3664
- var installType = ConfigReader.get('installType');
3664
+ var installType = ConfigReader.get('installType') || getPendoConfigFromEnclosingScope().installType;
3665
3665
  return installType || NATIVE_INSTALL_TYPE;
3666
3666
  }
3667
3667
  function isExtensionAgent() {
@@ -3903,8 +3903,8 @@ var SERVER = '';
3903
3903
  var ASSET_HOST = '';
3904
3904
  var ASSET_PATH = '';
3905
3905
  var DESIGNER_SERVER = '';
3906
- var VERSION = '2.287.1_';
3907
- var PACKAGE_VERSION = '2.287.1';
3906
+ var VERSION = '2.288.1_';
3907
+ var PACKAGE_VERSION = '2.288.1';
3908
3908
  var LOADER = 'xhr';
3909
3909
  /* eslint-enable agent-eslint-rules/no-gulp-env-references */
3910
3910
  /**
@@ -38065,7 +38065,7 @@ const FormValidation = (function () {
38065
38065
  })();
38066
38066
 
38067
38067
  class DOMPrompt {
38068
- constructor(pendo, PluginAPI, id, privacyFitlers, inputCssSelector, submitCssSelector) {
38068
+ constructor(pendo, PluginAPI, id, privacyFilters, inputCssSelectors, submitCssSelectors) {
38069
38069
  this.listeners = [];
38070
38070
  this.latestPromptValue = '';
38071
38071
  this.dom = pendo.dom;
@@ -38073,27 +38073,69 @@ class DOMPrompt {
38073
38073
  this.api = PluginAPI;
38074
38074
  this.q = PluginAPI.q;
38075
38075
  this.id = id;
38076
- this.setFilters(privacyFitlers);
38077
- this.inputEl = new this.dom.Element(inputCssSelector);
38078
- this.submitEl = new this.dom.Element(submitCssSelector);
38079
- this.inputEl.addEventListener('change', (evt) => {
38080
- // capture value from copy / paste
38081
- this.capturePromptValue();
38082
- }, true);
38083
- this.inputEl.addEventListener('keydown', (evt) => {
38084
- const wasEnterKey = evt.code === 'Enter' || evt.key === 'Enter' || evt.keyCode === 13;
38085
- if (wasEnterKey) {
38086
- this.submit(this.latestPromptValue);
38076
+ this.setFilters(privacyFilters);
38077
+ if (!this._.isArray(inputCssSelectors)) {
38078
+ this.api.log.error('inputCssSelectors must be an array, received:', typeof inputCssSelectors);
38079
+ inputCssSelectors = [];
38080
+ }
38081
+ if (!this._.isArray(submitCssSelectors)) {
38082
+ this.api.log.error('submitCssSelectors must be an array, received:', typeof submitCssSelectors);
38083
+ submitCssSelectors = [];
38084
+ }
38085
+ this.inputEls = this._.map(inputCssSelectors, cssSelector => new this.dom.Element(cssSelector));
38086
+ this.submitEls = this._.map(submitCssSelectors, cssSelector => new this.dom.Element(cssSelector));
38087
+ this.setupInputListeners();
38088
+ this.setupSubmitListeners();
38089
+ this.setupObserver();
38090
+ }
38091
+ setupInputListeners() {
38092
+ this._.each(this.inputEls, (inputEl) => {
38093
+ if (!inputEl) {
38094
+ return;
38087
38095
  }
38088
- }, true);
38089
- this.inputEl.addEventListener('keyup', (evt) => {
38090
- this.capturePromptValue();
38091
- }, true);
38092
- this.submitEl.addEventListener('click', () => {
38093
- this.submit(this.latestPromptValue);
38094
- }, true);
38096
+ inputEl.addEventListener('change', (evt) => {
38097
+ // capture value from copy / paste
38098
+ this.capturePromptValue();
38099
+ }, true);
38100
+ inputEl.addEventListener('keydown', (evt) => {
38101
+ const wasEnterKey = evt.code === 'Enter' || evt.key === 'Enter' || evt.keyCode === 13;
38102
+ if (wasEnterKey) {
38103
+ this.submit(this.latestPromptValue);
38104
+ }
38105
+ }, true);
38106
+ inputEl.addEventListener('keyup', (evt) => {
38107
+ this.capturePromptValue();
38108
+ }, true);
38109
+ });
38110
+ }
38111
+ setupSubmitListeners() {
38112
+ this._.each(this.submitEls, (submitEl) => {
38113
+ if (!submitEl) {
38114
+ return;
38115
+ }
38116
+ const clickHandler = (evt) => {
38117
+ // Capture current value at mousedown time, before app's click handlers run
38118
+ const currentValue = this.getPromptValue();
38119
+ const valueToSubmit = currentValue || this.latestPromptValue;
38120
+ this.submit(valueToSubmit);
38121
+ };
38122
+ submitEl.addEventListener('mousedown', clickHandler, true);
38123
+ const keydownHandler = (evt) => {
38124
+ const wasEnterKey = evt.code === 'Enter' || evt.key === 'Enter' || evt.keyCode === 13;
38125
+ if (wasEnterKey) {
38126
+ const currentValue = this.getPromptValue();
38127
+ const valueToSubmit = currentValue || this.latestPromptValue;
38128
+ this.submit(valueToSubmit);
38129
+ }
38130
+ };
38131
+ submitEl.addEventListener('keydown', keydownHandler, true);
38132
+ });
38133
+ }
38134
+ setupObserver() {
38095
38135
  this.promptContainer = new this.dom.Observer();
38096
- this.promptContainer.addObservers(this.inputEl, this.submitEl);
38136
+ const validInputEls = this._.filter(this.inputEls, el => el);
38137
+ const validSubmitEls = this._.filter(this.submitEls, el => el);
38138
+ this.promptContainer.addObservers(...validInputEls, ...validSubmitEls);
38097
38139
  }
38098
38140
  setFilters(candidateFilter) {
38099
38141
  if (!candidateFilter) {
@@ -38116,11 +38158,10 @@ class DOMPrompt {
38116
38158
  return candidateValue.replace(filtersToUse, 'redacted');
38117
38159
  }
38118
38160
  submit(origVal) {
38119
- // Don't submit an empty prompt
38120
- if (!origVal)
38161
+ if (!origVal) {
38121
38162
  return;
38163
+ }
38122
38164
  const val = this.applyPrivacyFilter(origVal);
38123
- // build the payload: id, value, was filter used
38124
38165
  const payload = {
38125
38166
  agentId: this.id,
38126
38167
  prompt: val,
@@ -38129,7 +38170,7 @@ class DOMPrompt {
38129
38170
  this._.each(this.listeners, (cb) => cb(payload));
38130
38171
  }
38131
38172
  /*
38132
- * Genernally we want to capture the value from "input" but there can be implementation
38173
+ * Generally we want to capture the value from "input" but there can be implementation
38133
38174
  * dependent scenarios where the input's value has already been cleared by the time
38134
38175
  * the event handler is called. So, in that case, we don't want to throw our saved value out.
38135
38176
  */
@@ -38141,15 +38182,44 @@ class DOMPrompt {
38141
38182
  return tmp;
38142
38183
  }
38143
38184
  getPromptValue() {
38144
- return this.inputEl.getText();
38185
+ const elementWithValue = this._.find(this.inputEls, (el) => {
38186
+ if (el) {
38187
+ try {
38188
+ const value = el.getText();
38189
+ return value && value.trim();
38190
+ }
38191
+ catch (err) {
38192
+ return false;
38193
+ }
38194
+ }
38195
+ return false;
38196
+ });
38197
+ if (elementWithValue) {
38198
+ try {
38199
+ const value = elementWithValue.getText();
38200
+ return value.trim();
38201
+ }
38202
+ catch (err) { }
38203
+ }
38204
+ return '';
38145
38205
  }
38146
38206
  onSubmit(callback) {
38147
38207
  this.listeners.push(callback);
38148
38208
  }
38149
38209
  teardown() {
38150
- this.promptContainer.teardown();
38151
- this.inputEl.teardown();
38152
- this.submitEl.teardown();
38210
+ if (this.promptContainer) {
38211
+ this.promptContainer.teardown();
38212
+ }
38213
+ this._.each(this.inputEls, (inputEl) => {
38214
+ if (inputEl) {
38215
+ inputEl.teardown();
38216
+ }
38217
+ });
38218
+ this._.each(this.submitEls, (submitEl) => {
38219
+ if (submitEl) {
38220
+ submitEl.teardown();
38221
+ }
38222
+ });
38153
38223
  }
38154
38224
  }
38155
38225
 
@@ -38274,17 +38344,19 @@ class PromptPlugin {
38274
38344
  }
38275
38345
  observePrompt(config) {
38276
38346
  const { id, cssSelectors, privacyFilters } = config;
38277
- let inputCssSelector, submitCssSelector;
38278
- inputCssSelector = this.parseCssSelector('input', cssSelectors);
38279
- submitCssSelector = this.parseCssSelector('submit', cssSelectors);
38280
- const prompt = new DOMPrompt(this.pendo, this.api, id, privacyFilters, inputCssSelector, submitCssSelector);
38347
+ let inputCssSelectors, submitCssSelectors;
38348
+ inputCssSelectors = this.parseCssSelector('input', cssSelectors);
38349
+ submitCssSelectors = this.parseCssSelector('submit', cssSelectors);
38350
+ const prompt = new DOMPrompt(this.pendo, this.api, id, privacyFilters, inputCssSelectors, submitCssSelectors);
38281
38351
  prompt.onSubmit((promptPayload) => {
38282
38352
  this.sendEvent(promptPayload);
38283
38353
  });
38284
38354
  this.prompts.push(prompt);
38285
38355
  }
38286
38356
  parseCssSelector(type, configs) {
38287
- return this._.find(configs, (target) => target.type === type).cssSelector;
38357
+ const filtered = this._.filter(configs, cfg => cfg.type === type);
38358
+ const selectors = this._.map(filtered, cfg => cfg.cssSelector);
38359
+ return selectors;
38288
38360
  }
38289
38361
  sendEvent(promptEvent) {
38290
38362
  const event = this._.extend({
@@ -47239,6 +47311,12 @@ class SessionRecorder {
47239
47311
  * will ensure that it and the snapshot events are sent together and first for the next session of events.
47240
47312
  */
47241
47313
  if (isMeta) {
47314
+ // Replace the URL captured by rrweb for META events with the location API aware version of the URL. This
47315
+ // makes sure the URL captured in replay respects any URL modification/obfuscation set up by end users
47316
+ // using the location API.
47317
+ if (this.pendo._.has(event, 'data.href')) {
47318
+ event.data.href = this.pendo.location.getHref();
47319
+ }
47242
47320
  this.send();
47243
47321
  }
47244
47322
  this.buffer.push(event);