@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 +7 -2
- package/dist/pendo.module.js +114 -36
- package/dist/pendo.module.min.js +9 -9
- package/package.json +1 -1
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.
|
|
7295
|
+
var VERSION = '2.288.1_';
|
|
7291
7296
|
|
|
7292
7297
|
var decodeURIComponent = _.isFunction(window.decodeURIComponent) ? window.decodeURIComponent : _.identity;
|
|
7293
7298
|
|
package/dist/pendo.module.js
CHANGED
|
@@ -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.
|
|
3907
|
-
var PACKAGE_VERSION = '2.
|
|
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,
|
|
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(
|
|
38077
|
-
|
|
38078
|
-
|
|
38079
|
-
|
|
38080
|
-
|
|
38081
|
-
|
|
38082
|
-
|
|
38083
|
-
|
|
38084
|
-
|
|
38085
|
-
|
|
38086
|
-
|
|
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
|
-
|
|
38089
|
-
|
|
38090
|
-
|
|
38091
|
-
|
|
38092
|
-
|
|
38093
|
-
|
|
38094
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
|
38151
|
-
|
|
38152
|
-
|
|
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
|
|
38278
|
-
|
|
38279
|
-
|
|
38280
|
-
const prompt = new DOMPrompt(this.pendo, this.api, id, privacyFilters,
|
|
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
|
-
|
|
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);
|