@pendo/agent 2.302.2 → 2.303.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
@@ -7359,7 +7359,7 @@ function getScreenPosition(element) {
7359
7359
  };
7360
7360
  }
7361
7361
 
7362
- var VERSION = '2.302.2_';
7362
+ var VERSION = '2.303.0_';
7363
7363
 
7364
7364
  var decodeURIComponent = _.isFunction(window.decodeURIComponent) ? window.decodeURIComponent : _.identity;
7365
7365
 
@@ -3904,8 +3904,8 @@ let SERVER = '';
3904
3904
  let ASSET_HOST = '';
3905
3905
  let ASSET_PATH = '';
3906
3906
  let DESIGNER_SERVER = '';
3907
- let VERSION = '2.302.2_';
3908
- let PACKAGE_VERSION = '2.302.2';
3907
+ let VERSION = '2.303.0_';
3908
+ let PACKAGE_VERSION = '2.303.0';
3909
3909
  let LOADER = 'xhr';
3910
3910
  /* eslint-enable agent-eslint-rules/no-gulp-env-references */
3911
3911
  /**
@@ -4203,6 +4203,12 @@ var getNumberFromText = function (text) {
4203
4203
  function isPromise(obj) {
4204
4204
  return _.isObject(obj) && _.isFunction(obj.then);
4205
4205
  }
4206
+ function unwrapFirefoxObject(obj) {
4207
+ if (obj && obj.hasOwnProperty('wrappedJSObject')) {
4208
+ return obj.wrappedJSObject;
4209
+ }
4210
+ return obj;
4211
+ }
4206
4212
 
4207
4213
  var decodeURIComponent = _.isFunction(window.decodeURIComponent) ? window.decodeURIComponent : _.identity;
4208
4214
 
@@ -14749,9 +14755,12 @@ function applyBehaviors(behaviors, obj) {
14749
14755
  function GuideFactory(guide) {
14750
14756
  if (_.isFunction(guide.before))
14751
14757
  return guide;
14758
+ guide = unwrapFirefoxObject(guide);
14752
14759
  return applyBehaviors(GuideFactory.behaviors, guide);
14753
14760
  }
14754
14761
  function GuideStepFactory(step, guide) {
14762
+ step = unwrapFirefoxObject(step);
14763
+ guide = unwrapFirefoxObject(guide);
14755
14764
  return applyBehaviors(GuideStepFactory.behaviors, step, guide);
14756
14765
  }
14757
14766
  GuideFactory.behaviors = [];
@@ -18182,6 +18191,7 @@ function getAllowedAttributes(attributeKeyValueMap, stepId, guideId, type) {
18182
18191
  }
18183
18192
  function buildNodeFromJSON(json, step, guides) {
18184
18193
  step = step || { id: 'unknown', guideId: 'unknown' };
18194
+ json = unwrapFirefoxObject(json);
18185
18195
  json.props = getAllowedAttributes(json.props, step.id, step.guideId, json.type);
18186
18196
  if (step.isDarkMode && json.darkModeProps) {
18187
18197
  json.darkModeProps = getAllowedAttributes(json.darkModeProps, step.id, step.guideId, json.type);
@@ -28808,7 +28818,8 @@ var BuildingBlockGuides = (function () {
28808
28818
  step.hasEscapeListener = false;
28809
28819
  step.containerId = containerJSON && containerJSON.props && containerJSON.props.id;
28810
28820
  step.element = getElementForGuideStep(step, options.document);
28811
- var guideToAppend = BuildingBlockGuides.buildNodeFromJSON(json, step, guides);
28821
+ var modifiableJSON = unwrapFirefoxObject(json);
28822
+ var guideToAppend = BuildingBlockGuides.buildNodeFromJSON(modifiableJSON, step, guides);
28812
28823
  step.guideElement = guideToAppend;
28813
28824
  var guideContainer = guideToAppend.find('#' + step.containerId);
28814
28825
  var verticalAlignmentAttr = 'data-vertical-alignment';
@@ -28844,22 +28855,29 @@ var BuildingBlockGuides = (function () {
28844
28855
  const guideContainerId = 'pendo-guide-container';
28845
28856
  const baseContainerId = 'pendo-base';
28846
28857
  const baseContainer = guideToAppend[0];
28847
- const pendoGuideContainer = baseContainer.querySelector(`#${guideContainerId}`);
28858
+ const pendoGuideContainer = dom(`#${guideContainerId}`, baseContainer)[0];
28848
28859
  if (pendoGuideContainer) {
28849
28860
  pendoGuideContainer.id = `${guideContainerId}-${step.id}`;
28850
28861
  baseContainer.id = `${baseContainerId}-${step.id}`;
28851
28862
  }
28852
28863
  const { selector, method } = embedConfig;
28853
28864
  parent = dom(selector)[0];
28854
- if (method === 'replace' && parent) {
28855
- parent.innerHTML = '';
28856
- guideToAppend.appendTo(parent);
28857
- }
28858
- else if (method === 'prepend') {
28859
- guideToAppend.prependTo(parent);
28865
+ const existingGuideElement = dom(`#${baseContainer.id}`, parent);
28866
+ if (existingGuideElement.length) { // The embedded guide may already exist due to page caching
28867
+ guideToAppend = existingGuideElement;
28868
+ step.guideElement = guideToAppend;
28860
28869
  }
28861
28870
  else {
28862
- guideToAppend.appendTo(parent);
28871
+ if (method === 'replace' && parent) {
28872
+ parent.innerHTML = '';
28873
+ guideToAppend.appendTo(parent);
28874
+ }
28875
+ else if (method === 'prepend') {
28876
+ guideToAppend.prependTo(parent);
28877
+ }
28878
+ else {
28879
+ guideToAppend.appendTo(parent);
28880
+ }
28863
28881
  }
28864
28882
  }
28865
28883
  else {
@@ -28896,7 +28914,7 @@ var BuildingBlockGuides = (function () {
28896
28914
  BuildingBlockTooltips.attachBBAdvanceActions(step);
28897
28915
  }
28898
28916
  if (relativeToElement && !hasImageCount) {
28899
- BuildingBlockTooltips.positionStepForTooltip(step, json, guideContainer[0]);
28917
+ BuildingBlockTooltips.positionStepForTooltip(step, modifiableJSON, guideContainer[0]);
28900
28918
  }
28901
28919
  if (isResourceCenter) {
28902
28920
  BuildingBlockResourceCenter.showHomeViewOrEmptyState(guide);
@@ -30868,7 +30886,7 @@ function joinShowPromises(promises) {
30868
30886
  // A group of one or more guide steps with no ordering.
30869
30887
  function Guide() {
30870
30888
  this.elements = [];
30871
- this.attributes = this.attributes || {};
30889
+ this.attributes = (this.attributes && unwrapFirefoxObject(this.attributes)) || {};
30872
30890
  if (this.attributes.device && this.attributes.device.type) {
30873
30891
  if (this.attributes.device.type == 'all') {
30874
30892
  this.attributes.device = { desktop: true, mobile: true };
@@ -39579,6 +39597,7 @@ class DOMPrompt {
39579
39597
  this.latestPromptValue = '';
39580
39598
  this.isActive = true;
39581
39599
  this.lastSubmitTime = 0;
39600
+ this.compositionState = new WeakMap();
39582
39601
  this.dom = pendo.dom;
39583
39602
  this._ = pendo._;
39584
39603
  this.api = PluginAPI;
@@ -39599,23 +39618,63 @@ class DOMPrompt {
39599
39618
  this.setupSubmitListeners();
39600
39619
  this.setupObserver();
39601
39620
  }
39621
+ isComposing(evt) {
39622
+ const target = evt.target;
39623
+ const isComposingFromState = target && this.compositionState.get(target);
39624
+ return evt.isComposing !== undefined ? evt.isComposing : isComposingFromState;
39625
+ }
39626
+ isEnterKey(evt) {
39627
+ return evt.code === 'Enter' || evt.key === 'Enter' || evt.keyCode === 13;
39628
+ }
39602
39629
  setupInputListeners() {
39603
39630
  this._.each(this.inputEls, (inputEl) => {
39604
39631
  if (!inputEl) {
39605
39632
  return;
39606
39633
  }
39634
+ // Handle IME composition events (Japanese, Chinese, etc.) to prevent premature
39635
+ // analytics collection during intermediate input states
39636
+ inputEl.addEventListener('compositionstart', (evt) => {
39637
+ const target = evt.target;
39638
+ if (target) {
39639
+ this.compositionState.set(target, true);
39640
+ }
39641
+ }, true);
39642
+ inputEl.addEventListener('compositionend', (evt) => {
39643
+ const target = evt.target;
39644
+ if (target) {
39645
+ this.compositionState.set(target, false);
39646
+ this.capturePromptValue();
39647
+ }
39648
+ }, true);
39649
+ inputEl.addEventListener('compositionupdate', (evt) => {
39650
+ const target = evt.target;
39651
+ if (target) {
39652
+ this.compositionState.set(target, true);
39653
+ }
39654
+ }, true);
39655
+ inputEl.addEventListener('blur', (evt) => {
39656
+ const target = evt.target;
39657
+ if (target) {
39658
+ this.compositionState.set(target, false);
39659
+ }
39660
+ }, true);
39661
+ inputEl.addEventListener('input', (evt) => {
39662
+ if (!this.isComposing(evt)) {
39663
+ this.capturePromptValue();
39664
+ }
39665
+ }, true);
39607
39666
  inputEl.addEventListener('change', (evt) => {
39608
- // capture value from copy / paste
39609
39667
  this.capturePromptValue();
39610
39668
  }, true);
39611
39669
  inputEl.addEventListener('keydown', (evt) => {
39612
- const wasEnterKey = evt.code === 'Enter' || evt.key === 'Enter' || evt.keyCode === 13;
39613
- if (wasEnterKey) {
39670
+ if (this.isEnterKey(evt) && !this.isComposing(evt)) {
39614
39671
  this.submit(this.latestPromptValue);
39615
39672
  }
39616
39673
  }, true);
39617
39674
  inputEl.addEventListener('keyup', (evt) => {
39618
- this.capturePromptValue();
39675
+ if (!this.isComposing(evt)) {
39676
+ this.capturePromptValue();
39677
+ }
39619
39678
  }, true);
39620
39679
  });
39621
39680
  }
@@ -39632,8 +39691,7 @@ class DOMPrompt {
39632
39691
  };
39633
39692
  submitEl.addEventListener('mousedown', clickHandler, true);
39634
39693
  const keydownHandler = (evt) => {
39635
- const wasEnterKey = evt.code === 'Enter' || evt.key === 'Enter' || evt.keyCode === 13;
39636
- if (wasEnterKey) {
39694
+ if (this.isEnterKey(evt)) {
39637
39695
  const currentValue = this.getPromptValue();
39638
39696
  const valueToSubmit = currentValue || this.latestPromptValue;
39639
39697
  this.submit(valueToSubmit);
@@ -40602,6 +40660,7 @@ function substitutionIcon(color, size) {
40602
40660
  }
40603
40661
 
40604
40662
  const requiredElement = '<span class="_pendo-required-indicator" style="color:red; font-style:italic;" title="Question is required"> *</span>';
40663
+ const requiredSyntax = '{required/}';
40605
40664
  const RequiredQuestions = {
40606
40665
  name: 'RequiredQuestions',
40607
40666
  script(step, guide, pendo) {
@@ -40624,14 +40683,23 @@ const RequiredQuestions = {
40624
40683
  }
40625
40684
  });
40626
40685
  }
40686
+ function getEligibleQuestions() {
40687
+ const allQuestions = step.guideElement.find(`[class*=-poll-question]:contains(${requiredSyntax})`);
40688
+ return pendo._.reduce(allQuestions, (eligibleQuestions, question) => {
40689
+ if (question.classList.contains('_pendo-yes-no-poll-question'))
40690
+ return eligibleQuestions;
40691
+ eligibleQuestions.push(question);
40692
+ return eligibleQuestions;
40693
+ }, []);
40694
+ }
40627
40695
  function processRequiredQuestions() {
40628
- let questions = step.guideElement.find('[class*=-poll-question]:contains({required/})');
40696
+ let questions = getEligibleQuestions();
40629
40697
  if (questions) {
40630
40698
  pendo._.forEach(questions, question => {
40631
40699
  let dataPendoPollId = question.getAttribute('data-pendo-poll-id');
40632
40700
  requiredPollIds.push(dataPendoPollId);
40633
40701
  pendo._.each(step.guideElement.find(`#${question.id} *, #${question.id}`), (element) => {
40634
- guideMarkdownUtil.removeMarkdownSyntax(element, '{required/}', '', pendo);
40702
+ guideMarkdownUtil.removeMarkdownSyntax(element, requiredSyntax, '', pendo);
40635
40703
  });
40636
40704
  step.guideElement.find(`#${question.id} p`).append(requiredElement);
40637
40705
  });
@@ -40698,7 +40766,7 @@ const RequiredQuestions = {
40698
40766
  },
40699
40767
  test(step, guide, pendo) {
40700
40768
  var _a;
40701
- let requiredQuestions = (_a = step.guideElement) === null || _a === void 0 ? void 0 : _a.find('[class*=-poll-question]:contains({required/})');
40769
+ let requiredQuestions = (_a = step.guideElement) === null || _a === void 0 ? void 0 : _a.find(`[class*=-poll-question]:contains(${requiredSyntax})`);
40702
40770
  return !pendo._.isUndefined(requiredQuestions) && pendo._.size(requiredQuestions);
40703
40771
  },
40704
40772
  designerListener(pendo) {
@@ -40731,13 +40799,15 @@ const RequiredQuestions = {
40731
40799
  dataPendoPollId = poll.getAttribute('data-pendo-poll-id');
40732
40800
  }
40733
40801
  let questionText;
40734
- if (pendo.dom(`[class*="-poll-question"][data-pendo-poll-id=${dataPendoPollId}]`)[0]) {
40802
+ const pollQuesiton = pendo.dom(`[class*="-poll-question"][data-pendo-poll-id=${dataPendoPollId}]`)[0];
40803
+ if (pollQuesiton) {
40735
40804
  questionText = pendo.dom(`[class*="-poll-question"][data-pendo-poll-id=${dataPendoPollId}]`)[0].textContent;
40736
40805
  }
40737
- if (pendo._.contains(questionText, '{required/}')) {
40806
+ const requiredSyntaxIndex = questionText.indexOf(requiredSyntax);
40807
+ if (requiredSyntaxIndex > -1) {
40738
40808
  pendo._.each(pendo.dom(`[data-pendo-poll-id=${dataPendoPollId}]:not(.pendo-radio)`), (element) => {
40739
40809
  pendo._.each(pendo.dom(`#${element.id} *:not(".pendo-radio"), #${element.id}:not(".pendo-radio")`), (item) => {
40740
- guideMarkdownUtil.removeMarkdownSyntax(item, '{required/}', '', pendo);
40810
+ guideMarkdownUtil.removeMarkdownSyntax(item, requiredSyntax, '', pendo);
40741
40811
  });
40742
40812
  });
40743
40813
  if (pendo.dom(`.bb-text[data-pendo-poll-id=${dataPendoPollId}] p`).length !== 0 || pendo.dom(`.bb-text[data-pendo-poll-id=${dataPendoPollId}] li`).length !== 0) {