@pendo/agent 2.287.0 → 2.288.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 +1 -1
- package/dist/pendo.module.js +120 -37
- package/dist/pendo.module.min.js +7 -7
- package/package.json +1 -1
package/dist/dom.esm.js
CHANGED
package/dist/pendo.module.js
CHANGED
|
@@ -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.0_';
|
|
3907
|
+
var PACKAGE_VERSION = '2.288.0';
|
|
3908
3908
|
var LOADER = 'xhr';
|
|
3909
3909
|
/* eslint-enable agent-eslint-rules/no-gulp-env-references */
|
|
3910
3910
|
/**
|
|
@@ -12149,8 +12149,13 @@ class LocalStorageEventBuffer {
|
|
|
12149
12149
|
* @label UNSENT_EVENTS_KEY
|
|
12150
12150
|
*/
|
|
12151
12151
|
storage.registry.addLocal(UNSENT_EVENTS_KEY);
|
|
12152
|
-
|
|
12153
|
-
|
|
12152
|
+
try {
|
|
12153
|
+
this.events = JSON.parse(storage.read(UNSENT_EVENTS_KEY) || '{}');
|
|
12154
|
+
storage.clear(UNSENT_EVENTS_KEY);
|
|
12155
|
+
}
|
|
12156
|
+
catch (e) {
|
|
12157
|
+
this.events = {};
|
|
12158
|
+
}
|
|
12154
12159
|
}
|
|
12155
12160
|
write(storage) {
|
|
12156
12161
|
if (_.size(this.events) > 0) {
|
|
@@ -38060,7 +38065,7 @@ const FormValidation = (function () {
|
|
|
38060
38065
|
})();
|
|
38061
38066
|
|
|
38062
38067
|
class DOMPrompt {
|
|
38063
|
-
constructor(pendo, PluginAPI, id,
|
|
38068
|
+
constructor(pendo, PluginAPI, id, privacyFilters, inputCssSelectors, submitCssSelectors) {
|
|
38064
38069
|
this.listeners = [];
|
|
38065
38070
|
this.latestPromptValue = '';
|
|
38066
38071
|
this.dom = pendo.dom;
|
|
@@ -38068,27 +38073,69 @@ class DOMPrompt {
|
|
|
38068
38073
|
this.api = PluginAPI;
|
|
38069
38074
|
this.q = PluginAPI.q;
|
|
38070
38075
|
this.id = id;
|
|
38071
|
-
this.setFilters(
|
|
38072
|
-
|
|
38073
|
-
|
|
38074
|
-
|
|
38075
|
-
|
|
38076
|
-
|
|
38077
|
-
|
|
38078
|
-
|
|
38079
|
-
|
|
38080
|
-
|
|
38081
|
-
|
|
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;
|
|
38082
38095
|
}
|
|
38083
|
-
|
|
38084
|
-
|
|
38085
|
-
|
|
38086
|
-
|
|
38087
|
-
|
|
38088
|
-
|
|
38089
|
-
|
|
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() {
|
|
38090
38135
|
this.promptContainer = new this.dom.Observer();
|
|
38091
|
-
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);
|
|
38092
38139
|
}
|
|
38093
38140
|
setFilters(candidateFilter) {
|
|
38094
38141
|
if (!candidateFilter) {
|
|
@@ -38111,11 +38158,10 @@ class DOMPrompt {
|
|
|
38111
38158
|
return candidateValue.replace(filtersToUse, 'redacted');
|
|
38112
38159
|
}
|
|
38113
38160
|
submit(origVal) {
|
|
38114
|
-
|
|
38115
|
-
if (!origVal)
|
|
38161
|
+
if (!origVal) {
|
|
38116
38162
|
return;
|
|
38163
|
+
}
|
|
38117
38164
|
const val = this.applyPrivacyFilter(origVal);
|
|
38118
|
-
// build the payload: id, value, was filter used
|
|
38119
38165
|
const payload = {
|
|
38120
38166
|
agentId: this.id,
|
|
38121
38167
|
prompt: val,
|
|
@@ -38124,7 +38170,7 @@ class DOMPrompt {
|
|
|
38124
38170
|
this._.each(this.listeners, (cb) => cb(payload));
|
|
38125
38171
|
}
|
|
38126
38172
|
/*
|
|
38127
|
-
*
|
|
38173
|
+
* Generally we want to capture the value from "input" but there can be implementation
|
|
38128
38174
|
* dependent scenarios where the input's value has already been cleared by the time
|
|
38129
38175
|
* the event handler is called. So, in that case, we don't want to throw our saved value out.
|
|
38130
38176
|
*/
|
|
@@ -38136,15 +38182,44 @@ class DOMPrompt {
|
|
|
38136
38182
|
return tmp;
|
|
38137
38183
|
}
|
|
38138
38184
|
getPromptValue() {
|
|
38139
|
-
|
|
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 '';
|
|
38140
38205
|
}
|
|
38141
38206
|
onSubmit(callback) {
|
|
38142
38207
|
this.listeners.push(callback);
|
|
38143
38208
|
}
|
|
38144
38209
|
teardown() {
|
|
38145
|
-
this.promptContainer
|
|
38146
|
-
|
|
38147
|
-
|
|
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
|
+
});
|
|
38148
38223
|
}
|
|
38149
38224
|
}
|
|
38150
38225
|
|
|
@@ -38269,17 +38344,19 @@ class PromptPlugin {
|
|
|
38269
38344
|
}
|
|
38270
38345
|
observePrompt(config) {
|
|
38271
38346
|
const { id, cssSelectors, privacyFilters } = config;
|
|
38272
|
-
let
|
|
38273
|
-
|
|
38274
|
-
|
|
38275
|
-
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);
|
|
38276
38351
|
prompt.onSubmit((promptPayload) => {
|
|
38277
38352
|
this.sendEvent(promptPayload);
|
|
38278
38353
|
});
|
|
38279
38354
|
this.prompts.push(prompt);
|
|
38280
38355
|
}
|
|
38281
38356
|
parseCssSelector(type, configs) {
|
|
38282
|
-
|
|
38357
|
+
const filtered = this._.filter(configs, cfg => cfg.type === type);
|
|
38358
|
+
const selectors = this._.map(filtered, cfg => cfg.cssSelector);
|
|
38359
|
+
return selectors;
|
|
38283
38360
|
}
|
|
38284
38361
|
sendEvent(promptEvent) {
|
|
38285
38362
|
const event = this._.extend({
|
|
@@ -47234,6 +47311,12 @@ class SessionRecorder {
|
|
|
47234
47311
|
* will ensure that it and the snapshot events are sent together and first for the next session of events.
|
|
47235
47312
|
*/
|
|
47236
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
|
+
}
|
|
47237
47320
|
this.send();
|
|
47238
47321
|
}
|
|
47239
47322
|
this.buffer.push(event);
|