@pendo/agent 2.284.0 → 2.285.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/debugger-plugin.min.js +4 -1
- package/dist/dom.esm.js +9 -19
- package/dist/pendo.debugger.min.js +17 -50
- package/dist/pendo.module.js +384 -120
- package/dist/pendo.module.min.js +10 -10
- package/dist/pendo.preview.min.js +8 -44
- package/dist/replay.worker.min.js +3 -3
- package/package.json +1 -1
package/dist/pendo.module.js
CHANGED
|
@@ -454,7 +454,7 @@ function isMinifiedAgent(config) {
|
|
|
454
454
|
return !config.unminified;
|
|
455
455
|
}
|
|
456
456
|
function isExtension(config) {
|
|
457
|
-
return config.installType === 'extension';
|
|
457
|
+
return config.installType === 'extension'; // can't use isExtensionAgent() here because of circular dependency and ConfigReader not being ready yet
|
|
458
458
|
}
|
|
459
459
|
function shouldUseStagingAgent(config) {
|
|
460
460
|
return !isExtension(config) && !isStagingEnvironment(config) && isStagingServer(config);
|
|
@@ -3666,6 +3666,9 @@ function getInstallType() {
|
|
|
3666
3666
|
var installType = ConfigReader.get('installType');
|
|
3667
3667
|
return installType || NATIVE_INSTALL_TYPE;
|
|
3668
3668
|
}
|
|
3669
|
+
function isExtensionAgent() {
|
|
3670
|
+
return getInstallType() === EXTENSION_INSTALL_TYPE;
|
|
3671
|
+
}
|
|
3669
3672
|
function subscriptionBucketPrefix(env) {
|
|
3670
3673
|
if (env === PROD) {
|
|
3671
3674
|
return 'pendo-static';
|
|
@@ -3765,6 +3768,7 @@ if (bodyStyle) {
|
|
|
3765
3768
|
animations = _.isString(pdocument.body.style.webkitAnimation);
|
|
3766
3769
|
}
|
|
3767
3770
|
}
|
|
3771
|
+
var isChromeExtension = window.chrome && window.chrome.runtime && window.chrome.runtime.id;
|
|
3768
3772
|
// Android has history.pushState, but it does not update location correctly
|
|
3769
3773
|
// so let's not use the history API at all.
|
|
3770
3774
|
// http://code.google.com/p/android/issues/detail?id=17471
|
|
@@ -3778,15 +3782,13 @@ var shouldWrapNativeHistory = _.memoize(function shouldWrapNativeHistory() {
|
|
|
3778
3782
|
var historyDescriptors = window.history && _.isFunction(Object.getOwnPropertyDescriptors) && Object.getOwnPropertyDescriptors(window.history);
|
|
3779
3783
|
var isHistoryWriteable = historyDescriptors && _.get(historyDescriptors, 'pushState.writable', true) && _.get(historyDescriptors, 'replaceState.writable', true);
|
|
3780
3784
|
var hasAndroidSupport = !(android < 4);
|
|
3781
|
-
|
|
3782
|
-
return !!(hasNativeHistory && !isHistoryFrozen && isHistoryWriteable && hasAndroidSupport && !boxee && !isExtension);
|
|
3785
|
+
return !!(hasNativeHistory && !isHistoryFrozen && isHistoryWriteable && hasAndroidSupport && !boxee && !isExtensionAgent());
|
|
3783
3786
|
});
|
|
3784
3787
|
function shouldWrapHashChange() {
|
|
3785
3788
|
var hasNativeHashChange = 'onhashchange' in window;
|
|
3786
3789
|
// IE8 compatible mode lies
|
|
3787
3790
|
var hasSupportedDocMode = (!documentMode || documentMode > 7);
|
|
3788
|
-
|
|
3789
|
-
return !!(hasNativeHashChange && hasSupportedDocMode && !isExtension);
|
|
3791
|
+
return !!(hasNativeHashChange && hasSupportedDocMode && !isExtensionAgent());
|
|
3790
3792
|
}
|
|
3791
3793
|
function isMobileUserAgent() {
|
|
3792
3794
|
return (/Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i).test(getUA());
|
|
@@ -3820,7 +3822,8 @@ var sniffer = {
|
|
|
3820
3822
|
addEventListener: _.isFunction(window.addEventListener),
|
|
3821
3823
|
MutationObserver: isNativeCode(window.MutationObserver),
|
|
3822
3824
|
isMinimumIEVersion,
|
|
3823
|
-
isMobileUserAgent: _.memoize(isMobileUserAgent)
|
|
3825
|
+
isMobileUserAgent: _.memoize(isMobileUserAgent),
|
|
3826
|
+
isChromeExtension
|
|
3824
3827
|
};
|
|
3825
3828
|
|
|
3826
3829
|
var isBrowserInQuirksmode = function () {
|
|
@@ -3902,8 +3905,8 @@ var SERVER = '';
|
|
|
3902
3905
|
var ASSET_HOST = '';
|
|
3903
3906
|
var ASSET_PATH = '';
|
|
3904
3907
|
var DESIGNER_SERVER = '';
|
|
3905
|
-
var VERSION = '2.
|
|
3906
|
-
var PACKAGE_VERSION = '2.
|
|
3908
|
+
var VERSION = '2.285.0_';
|
|
3909
|
+
var PACKAGE_VERSION = '2.285.0';
|
|
3907
3910
|
var LOADER = 'xhr';
|
|
3908
3911
|
/* eslint-enable agent-eslint-rules/no-gulp-env-references */
|
|
3909
3912
|
/**
|
|
@@ -3930,10 +3933,6 @@ var overwriteBuiltConfigWithPendoConfig = function () {
|
|
|
3930
3933
|
var versionSuffix = isExtensionAgent() ? ENV + '_ext' : ENV;
|
|
3931
3934
|
VERSION = PACKAGE_VERSION + '_' + versionSuffix;
|
|
3932
3935
|
};
|
|
3933
|
-
function isExtensionAgent() {
|
|
3934
|
-
const installType = getPendoConfigValue('installType') || getPendoConfigFromEnclosingScope().installType;
|
|
3935
|
-
return installType === EXTENSION_INSTALL_TYPE;
|
|
3936
|
-
}
|
|
3937
3936
|
function isProdAgent() {
|
|
3938
3937
|
return ENV.indexOf('prod') !== -1;
|
|
3939
3938
|
}
|
|
@@ -9464,8 +9463,13 @@ function getAssetHost() {
|
|
|
9464
9463
|
}
|
|
9465
9464
|
return assetHost;
|
|
9466
9465
|
}
|
|
9466
|
+
function isLocalAgent(assetHost) {
|
|
9467
|
+
return assetHost.indexOf('localhost') >= 0 || assetHost.indexOf('local.pendo.io') >= 0;
|
|
9468
|
+
}
|
|
9467
9469
|
function getAssetUrl(filename) {
|
|
9468
|
-
|
|
9470
|
+
const assetHost = getAssetHost();
|
|
9471
|
+
const file = isLocalAgent(assetHost) ? filename.replace('.min.js', '.js') : filename;
|
|
9472
|
+
return `${assetHost}/${ASSET_PATH ? ASSET_PATH + '/' : ''}${file}`;
|
|
9469
9473
|
}
|
|
9470
9474
|
|
|
9471
9475
|
function treatAsAdoptPartner() {
|
|
@@ -13827,36 +13831,44 @@ function setFrameVisibility(visibility) {
|
|
|
13827
13831
|
return store.dispatch('frames/updateFrameVisibility', { visibility });
|
|
13828
13832
|
}
|
|
13829
13833
|
|
|
13830
|
-
|
|
13831
|
-
|
|
13832
|
-
|
|
13833
|
-
|
|
13834
|
-
|
|
13835
|
-
|
|
13836
|
-
|
|
13837
|
-
|
|
13838
|
-
|
|
13839
|
-
|
|
13840
|
-
|
|
13841
|
-
|
|
13842
|
-
|
|
13843
|
-
|
|
13844
|
-
|
|
13845
|
-
|
|
13846
|
-
|
|
13847
|
-
|
|
13848
|
-
|
|
13849
|
-
|
|
13850
|
-
|
|
13851
|
-
|
|
13852
|
-
|
|
13853
|
-
|
|
13854
|
-
], function (eventName) {
|
|
13834
|
+
const useAsync = {
|
|
13835
|
+
validateGuide: 1,
|
|
13836
|
+
validateLauncher: 1,
|
|
13837
|
+
validateGlobalScript: 1
|
|
13838
|
+
};
|
|
13839
|
+
const internalEvents = {
|
|
13840
|
+
ready: 1,
|
|
13841
|
+
deliverablesLoaded: 1,
|
|
13842
|
+
guidesFailed: 1,
|
|
13843
|
+
guidesLoaded: 1,
|
|
13844
|
+
onClickCaptured: 1
|
|
13845
|
+
};
|
|
13846
|
+
const supportedPublicEvents = [
|
|
13847
|
+
'ready',
|
|
13848
|
+
'onClickCaptured',
|
|
13849
|
+
'deliverablesLoaded',
|
|
13850
|
+
'guidesFailed',
|
|
13851
|
+
'guidesLoaded',
|
|
13852
|
+
'validateGuide',
|
|
13853
|
+
'validateLauncher',
|
|
13854
|
+
'validateGlobalScript'
|
|
13855
|
+
];
|
|
13856
|
+
function forwardInternalEvents(Events) {
|
|
13857
|
+
const unsubscribes = _.reduce(supportedPublicEvents, function (unsubscribes, eventName) {
|
|
13855
13858
|
if (internalEvents[eventName]) {
|
|
13856
|
-
|
|
13859
|
+
const forward = function (event) {
|
|
13857
13860
|
return PublicEvents[eventName].apply(PublicEvents[eventName], event.data);
|
|
13858
|
-
}
|
|
13861
|
+
};
|
|
13862
|
+
Events[eventName].on(forward);
|
|
13863
|
+
unsubscribes.push(() => Events[eventName].off(forward));
|
|
13859
13864
|
}
|
|
13865
|
+
return unsubscribes;
|
|
13866
|
+
}, []);
|
|
13867
|
+
return () => _.each(unsubscribes, (unsubscribe) => unsubscribe());
|
|
13868
|
+
}
|
|
13869
|
+
var PublicEvents = (function () {
|
|
13870
|
+
var events = Eventable.call({});
|
|
13871
|
+
_.each(supportedPublicEvents, function (eventName) {
|
|
13860
13872
|
events[eventName] = function (callback) {
|
|
13861
13873
|
if (_.isFunction(callback)) {
|
|
13862
13874
|
return events.on(eventName, callback);
|
|
@@ -14677,10 +14689,12 @@ var GuideRuntime = (function (agentEvents) {
|
|
|
14677
14689
|
var EventChannel = agentEvents.runtime;
|
|
14678
14690
|
const pluginAddGlobalScripts = [];
|
|
14679
14691
|
function initialize() {
|
|
14692
|
+
EventChannel.on(handleEvent);
|
|
14680
14693
|
const globalScripts = ConfigReader.get('guides.globalScripts');
|
|
14681
14694
|
_.each(globalScripts, GuideRuntime.addGlobalScript);
|
|
14682
14695
|
}
|
|
14683
14696
|
function teardown() {
|
|
14697
|
+
EventChannel.off(handleEvent);
|
|
14684
14698
|
_.each(pluginAddGlobalScripts, GuideRuntime.removeGlobalScript);
|
|
14685
14699
|
}
|
|
14686
14700
|
function addGlobalScript(obj) {
|
|
@@ -14816,7 +14830,7 @@ var GuideRuntime = (function (agentEvents) {
|
|
|
14816
14830
|
return 'hidden';
|
|
14817
14831
|
return step.seenState;
|
|
14818
14832
|
}
|
|
14819
|
-
|
|
14833
|
+
function handleEvent(evt) {
|
|
14820
14834
|
var step = evt.data[0];
|
|
14821
14835
|
evt.step = step;
|
|
14822
14836
|
delete evt.data;
|
|
@@ -14841,7 +14855,7 @@ var GuideRuntime = (function (agentEvents) {
|
|
|
14841
14855
|
delete evt.cancel;
|
|
14842
14856
|
}
|
|
14843
14857
|
return evt;
|
|
14844
|
-
}
|
|
14858
|
+
}
|
|
14845
14859
|
function GuideRuntimeContext(step) {
|
|
14846
14860
|
this.step = step;
|
|
14847
14861
|
_.each(['read', 'write', 'clear'], function (action) {
|
|
@@ -15864,6 +15878,16 @@ function vertical(elementPos, screenDim, layoutDir) {
|
|
|
15864
15878
|
return TOP;
|
|
15865
15879
|
}
|
|
15866
15880
|
|
|
15881
|
+
const TOOLTIP_CONSTANTS = {
|
|
15882
|
+
DEFAULT_CARET_OFFSET: 10,
|
|
15883
|
+
BOUNDARY_MARGIN_RIGHT: 0.98,
|
|
15884
|
+
BOUNDARY_MARGIN_LEFT: 0.02,
|
|
15885
|
+
Z_INDEX: {
|
|
15886
|
+
DEFAULT: '300000',
|
|
15887
|
+
CARET: 11,
|
|
15888
|
+
BORDER_CARET: 10
|
|
15889
|
+
}
|
|
15890
|
+
};
|
|
15867
15891
|
var BuildingBlockTooltips = (function () {
|
|
15868
15892
|
return {
|
|
15869
15893
|
createBBTooltip,
|
|
@@ -15882,8 +15906,25 @@ var BuildingBlockTooltips = (function () {
|
|
|
15882
15906
|
attachBBAdvanceActions,
|
|
15883
15907
|
attachScrollHandlers,
|
|
15884
15908
|
isBuildingBlockGuideRelativeToElement,
|
|
15885
|
-
positionStepForTooltip
|
|
15909
|
+
positionStepForTooltip,
|
|
15910
|
+
patchGuideContainerWidthForResponsiveTooltips
|
|
15886
15911
|
};
|
|
15912
|
+
function patchGuideContainerWidthForResponsiveTooltips(step, providedGuideContainer, json) {
|
|
15913
|
+
const guideContainer = providedGuideContainer || getGuideContainer(step);
|
|
15914
|
+
if (!guideContainer)
|
|
15915
|
+
return;
|
|
15916
|
+
const element = step.element || getElementForGuideStep(step);
|
|
15917
|
+
if (!element)
|
|
15918
|
+
return;
|
|
15919
|
+
const width = guideContainer.style.width;
|
|
15920
|
+
if (!width || width.indexOf('vw') === -1) {
|
|
15921
|
+
return;
|
|
15922
|
+
}
|
|
15923
|
+
const tooltipContext = getTooltipPositioningContext(step, element, json, guideContainer);
|
|
15924
|
+
if (!tooltipContext)
|
|
15925
|
+
return;
|
|
15926
|
+
calculateVwRelativeToLayoutDir(guideContainer, tooltipContext);
|
|
15927
|
+
}
|
|
15887
15928
|
function positionStepForTooltip(step, json, guideContainerEle) {
|
|
15888
15929
|
// This directly modifies step.guideElement object
|
|
15889
15930
|
createBBTooltip(json, step.element, step, guideContainerEle);
|
|
@@ -15896,39 +15937,58 @@ var BuildingBlockTooltips = (function () {
|
|
|
15896
15937
|
function buildTooltipCSSName() {
|
|
15897
15938
|
return treatAsMobileDevice() ? MOBILE_TOOLTIP_CSS_NAME : TOOLTIP_CSS_NAME;
|
|
15898
15939
|
}
|
|
15899
|
-
function
|
|
15900
|
-
if (!step.guideElement)
|
|
15901
|
-
return;
|
|
15902
|
-
var tooltipDiv = step.guideElement;
|
|
15903
|
-
tooltipDiv.addClass(buildTooltipCSSName());
|
|
15940
|
+
function getTooltipPositioningContext(step, element, json, guideContainer) {
|
|
15904
15941
|
var elementPos = getOffsetPosition(element);
|
|
15942
|
+
var screenPos = getScreenPosition(element);
|
|
15943
|
+
var screenDimensions = getScreenDimensions();
|
|
15944
|
+
var layoutDir = step.attributes.layoutDir || 'auto';
|
|
15905
15945
|
// RETURN IF THE FOUND ELEMENT IS NOT VISIBLE ON THE SCREEN.
|
|
15906
15946
|
if (elementPos.height === 0 && elementPos.width === 0) {
|
|
15907
15947
|
return null;
|
|
15908
15948
|
}
|
|
15909
|
-
|
|
15949
|
+
const elementIsNotVisible = step && !step.elementPathRule;
|
|
15910
15950
|
var containerTruthTest = function (block) { return block.props.id === 'pendo-guide-container'; };
|
|
15911
|
-
var containerDomJson = findDomBlockInDomJson(
|
|
15951
|
+
var containerDomJson = findDomBlockInDomJson(json, containerTruthTest);
|
|
15912
15952
|
if (!containerDomJson)
|
|
15913
|
-
return;
|
|
15914
|
-
var layoutDir = step.attributes.layoutDir;
|
|
15915
|
-
var tooltipSizes = {
|
|
15916
|
-
height: guideContainer.offsetHeight,
|
|
15917
|
-
width: guideContainer.offsetWidth
|
|
15918
|
-
};
|
|
15953
|
+
return null;
|
|
15919
15954
|
var caretDimensions = {
|
|
15920
15955
|
height: parseInt(containerDomJson.props['data-caret-height'], 10) || 0,
|
|
15921
15956
|
width: parseInt(containerDomJson.props['data-caret-width'], 10) || 0,
|
|
15922
15957
|
backgroundColor: containerDomJson.props.style['background-color'],
|
|
15923
|
-
offset:
|
|
15958
|
+
offset: TOOLTIP_CONSTANTS.DEFAULT_CARET_OFFSET,
|
|
15959
|
+
borderWidth: 0
|
|
15924
15960
|
};
|
|
15925
|
-
attachBBAdvanceActions(step);
|
|
15926
15961
|
if (containerDomJson.props.style.border) {
|
|
15927
15962
|
var guideBorderArray = containerDomJson.props.style.border.split(' ');
|
|
15928
15963
|
caretDimensions.borderColor = guideBorderArray[2];
|
|
15929
15964
|
caretDimensions.borderWidth = parseInt(guideBorderArray[0], 10);
|
|
15930
15965
|
}
|
|
15931
|
-
|
|
15966
|
+
const tooltipSizes = {
|
|
15967
|
+
width: guideContainer.offsetWidth,
|
|
15968
|
+
height: guideContainer.offsetHeight,
|
|
15969
|
+
layoutDir
|
|
15970
|
+
};
|
|
15971
|
+
return {
|
|
15972
|
+
elementPos,
|
|
15973
|
+
screenPos,
|
|
15974
|
+
screenDimensions,
|
|
15975
|
+
caretDimensions,
|
|
15976
|
+
tooltipSizes,
|
|
15977
|
+
containerDomJson,
|
|
15978
|
+
elementIsNotVisible
|
|
15979
|
+
};
|
|
15980
|
+
}
|
|
15981
|
+
function createBBTooltip(domJson, element, step, guideContainer) {
|
|
15982
|
+
if (!step.guideElement)
|
|
15983
|
+
return;
|
|
15984
|
+
const tooltipContext = getTooltipPositioningContext(step, element, domJson, guideContainer);
|
|
15985
|
+
if (!tooltipContext)
|
|
15986
|
+
return null;
|
|
15987
|
+
const { elementPos, tooltipSizes, screenPos, caretDimensions } = tooltipContext;
|
|
15988
|
+
var tooltipDiv = step.guideElement;
|
|
15989
|
+
tooltipDiv.addClass(buildTooltipCSSName());
|
|
15990
|
+
attachBBAdvanceActions(step);
|
|
15991
|
+
var tooltipDimensions = getBBTooltipDimensions(elementPos, { height: tooltipSizes.height, width: tooltipSizes.width }, caretDimensions, step.attributes.layoutDir, screenPos);
|
|
15932
15992
|
if (step) {
|
|
15933
15993
|
step.dim = tooltipDimensions;
|
|
15934
15994
|
}
|
|
@@ -15946,15 +16006,13 @@ var BuildingBlockTooltips = (function () {
|
|
|
15946
16006
|
guideContainer.style.position = 'absolute';
|
|
15947
16007
|
}
|
|
15948
16008
|
if (caretDimensions.height && caretDimensions.width) {
|
|
15949
|
-
buildTooltipCaret(tooltipDiv, tooltipDimensions, caretDimensions);
|
|
16009
|
+
buildTooltipCaret(tooltipDiv, tooltipDimensions, caretDimensions, elementPos);
|
|
15950
16010
|
}
|
|
15951
|
-
var inheritedZIndex =
|
|
16011
|
+
var inheritedZIndex = TOOLTIP_CONSTANTS.Z_INDEX.DEFAULT;
|
|
15952
16012
|
if (guideContainer && guideContainer.style && guideContainer.style['z-index']) {
|
|
15953
16013
|
inheritedZIndex = guideContainer.style['z-index'];
|
|
15954
16014
|
}
|
|
15955
|
-
//
|
|
15956
16015
|
// styles for OUTER Guide
|
|
15957
|
-
//
|
|
15958
16016
|
tooltipDiv.css({
|
|
15959
16017
|
'z-index': inheritedZIndex
|
|
15960
16018
|
});
|
|
@@ -16021,7 +16079,7 @@ var BuildingBlockTooltips = (function () {
|
|
|
16021
16079
|
tooltipDimensions.hbias = horizontal(elementPos, screenDimensions, layoutDirection);
|
|
16022
16080
|
tooltipDimensions.vbias = vertical(elementPos, screenDimensions, layoutDirection);
|
|
16023
16081
|
tooltipDimensions.layoutDir = determineTooltipPosition(tooltipDimensions, screenDimensions, screenPos, layoutDirection);
|
|
16024
|
-
var tooltipPosition = positionBBTooltipWithBias(tooltipDimensions, elementPos, screenDimensions);
|
|
16082
|
+
var tooltipPosition = positionBBTooltipWithBias(tooltipDimensions, elementPos, screenDimensions, caretSizes);
|
|
16025
16083
|
tooltipDimensions.top = tooltipPosition.top;
|
|
16026
16084
|
tooltipDimensions.left = tooltipPosition.left;
|
|
16027
16085
|
// Adjust tooltip top/left for the size of the caret
|
|
@@ -16039,6 +16097,32 @@ var BuildingBlockTooltips = (function () {
|
|
|
16039
16097
|
}
|
|
16040
16098
|
return tooltipDimensions;
|
|
16041
16099
|
}
|
|
16100
|
+
function calculateVwRelativeToLayoutDir(guideContainer, tooltipContext) {
|
|
16101
|
+
const { elementPos, tooltipSizes, screenDimensions, caretDimensions, elementIsNotVisible } = tooltipContext;
|
|
16102
|
+
const caretFullWidth = (parseInt(caretDimensions.width, 10) || 0);
|
|
16103
|
+
const maxWidth = parseInt(guideContainer.style.maxWidth, 10);
|
|
16104
|
+
const minWidth = parseInt(guideContainer.style.minWidth, 10);
|
|
16105
|
+
const percentage = parseFloat(guideContainer.style.width) / 100;
|
|
16106
|
+
if (elementIsNotVisible) {
|
|
16107
|
+
tooltipSizes.width -= caretFullWidth;
|
|
16108
|
+
}
|
|
16109
|
+
else if (tooltipSizes.layoutDir === 'left') {
|
|
16110
|
+
const availableSpaceToTheLeftOfElement = elementPos.left - caretFullWidth;
|
|
16111
|
+
tooltipSizes.width = Math.max(0, availableSpaceToTheLeftOfElement * percentage);
|
|
16112
|
+
}
|
|
16113
|
+
else if (tooltipSizes.layoutDir === 'right') {
|
|
16114
|
+
const availableSpaceToTheRightOfElement = screenDimensions.width - elementPos.right - caretFullWidth;
|
|
16115
|
+
tooltipSizes.width = Math.max(0, availableSpaceToTheRightOfElement * percentage);
|
|
16116
|
+
}
|
|
16117
|
+
if (maxWidth && tooltipSizes.width > maxWidth) {
|
|
16118
|
+
tooltipSizes.width = maxWidth;
|
|
16119
|
+
}
|
|
16120
|
+
if (minWidth && tooltipSizes.width < minWidth) {
|
|
16121
|
+
tooltipSizes.width = minWidth;
|
|
16122
|
+
}
|
|
16123
|
+
// We need to patch the vw to the available space for the tooltip, otherwise 100vw would be the entire screen
|
|
16124
|
+
guideContainer.style.width = tooltipSizes.width + 'px';
|
|
16125
|
+
}
|
|
16042
16126
|
function determineTooltipPosition(tooltipDimensions, screenDimensions, screenPos, layoutDirection) {
|
|
16043
16127
|
if (layoutDirection && layoutDirection !== 'auto') {
|
|
16044
16128
|
return layoutDirection;
|
|
@@ -16096,15 +16180,14 @@ var BuildingBlockTooltips = (function () {
|
|
|
16096
16180
|
return position;
|
|
16097
16181
|
return tooltipDimensions.hbias ? tooltipDimensions.hbias : 'bottom';
|
|
16098
16182
|
}
|
|
16099
|
-
function positionBBTooltipWithBias(tooltipDimensions, elementPosition, screenDimensions) {
|
|
16183
|
+
function positionBBTooltipWithBias(tooltipDimensions, elementPosition, screenDimensions, caretSizes) {
|
|
16100
16184
|
if (tooltipDimensions.layoutDir === 'top' || tooltipDimensions.layoutDir === 'bottom') {
|
|
16101
|
-
return calculateToolTipPositionForTopBottom(tooltipDimensions, screenDimensions, elementPosition, tooltipDimensions.layoutDir, tooltipDimensions.hbias);
|
|
16185
|
+
return calculateToolTipPositionForTopBottom(tooltipDimensions, screenDimensions, elementPosition, tooltipDimensions.layoutDir, tooltipDimensions.hbias, caretSizes);
|
|
16102
16186
|
}
|
|
16103
16187
|
return calculateToolTipPositionForLeftRight(tooltipDimensions, screenDimensions, elementPosition, tooltipDimensions.vbias);
|
|
16104
16188
|
}
|
|
16105
|
-
function calculateToolTipPositionForTopBottom(tooltipDimensions, screenDimensions, elementPosition, layoutDirection, horizontalBias) {
|
|
16189
|
+
function calculateToolTipPositionForTopBottom(tooltipDimensions, screenDimensions, elementPosition, layoutDirection, horizontalBias, caretSizes) {
|
|
16106
16190
|
var height = tooltipDimensions.height;
|
|
16107
|
-
var width = tooltipDimensions.width;
|
|
16108
16191
|
var tooltipPosition = {
|
|
16109
16192
|
top: null,
|
|
16110
16193
|
left: null
|
|
@@ -16115,22 +16198,95 @@ var BuildingBlockTooltips = (function () {
|
|
|
16115
16198
|
else if (layoutDirection === 'top') {
|
|
16116
16199
|
tooltipPosition.top = elementPosition.top - height;
|
|
16117
16200
|
}
|
|
16201
|
+
const boundaries = getBoundaries();
|
|
16118
16202
|
if (horizontalBias === 'right') {
|
|
16119
|
-
|
|
16120
|
-
if (leftVal + tooltipDimensions.width > screenDimensions.width) {
|
|
16121
|
-
leftVal -= (leftVal + tooltipDimensions.width - screenDimensions.width);
|
|
16122
|
-
}
|
|
16123
|
-
tooltipPosition.left = leftVal;
|
|
16203
|
+
tooltipPosition.left = calculateRightBiasPosition(elementPosition, tooltipDimensions, caretSizes, screenDimensions, boundaries.right, boundaries.left);
|
|
16124
16204
|
}
|
|
16125
16205
|
else if (horizontalBias === 'left') {
|
|
16126
|
-
tooltipPosition.left = elementPosition
|
|
16206
|
+
tooltipPosition.left = calculateLeftBiasPosition(elementPosition, tooltipDimensions, caretSizes, boundaries.right, boundaries.left);
|
|
16127
16207
|
}
|
|
16128
16208
|
else {
|
|
16129
16209
|
// ASSUME CENTER
|
|
16130
|
-
tooltipPosition.left = elementPosition
|
|
16210
|
+
tooltipPosition.left = calculateCenterBiasPosition(elementPosition, tooltipDimensions, boundaries.right, boundaries.left);
|
|
16131
16211
|
}
|
|
16132
16212
|
return tooltipPosition;
|
|
16133
16213
|
}
|
|
16214
|
+
function getBoundaries() {
|
|
16215
|
+
return {
|
|
16216
|
+
right: window.innerWidth * TOOLTIP_CONSTANTS.BOUNDARY_MARGIN_RIGHT,
|
|
16217
|
+
left: window.innerWidth * TOOLTIP_CONSTANTS.BOUNDARY_MARGIN_LEFT
|
|
16218
|
+
};
|
|
16219
|
+
}
|
|
16220
|
+
function calculateCaretPadding(caretSizes) {
|
|
16221
|
+
return caretSizes.offset + caretSizes.width + caretSizes.borderWidth;
|
|
16222
|
+
}
|
|
16223
|
+
function calculateRightBiasPosition(elementPosition, tooltipDimensions, caretSizes, screenDimensions, rightBoundary, leftBoundary) {
|
|
16224
|
+
const caretPadding = calculateCaretPadding(caretSizes);
|
|
16225
|
+
const width = tooltipDimensions.width;
|
|
16226
|
+
var leftVal = elementPosition.left + (elementPosition.width / 2) - caretPadding;
|
|
16227
|
+
if (leftVal + tooltipDimensions.width > screenDimensions.width) {
|
|
16228
|
+
leftVal -= (leftVal + tooltipDimensions.width - screenDimensions.width);
|
|
16229
|
+
}
|
|
16230
|
+
const tooltipRight = leftVal + width;
|
|
16231
|
+
if (tooltipRight > rightBoundary) {
|
|
16232
|
+
const overflow = tooltipRight - rightBoundary;
|
|
16233
|
+
if (leftVal - overflow < leftBoundary) {
|
|
16234
|
+
return spaceEvenly(leftVal, width);
|
|
16235
|
+
}
|
|
16236
|
+
else {
|
|
16237
|
+
return leftVal - overflow;
|
|
16238
|
+
}
|
|
16239
|
+
}
|
|
16240
|
+
return leftVal;
|
|
16241
|
+
}
|
|
16242
|
+
function calculateLeftBiasPosition(elementPosition, tooltipDimensions, caretSizes, rightBoundary, leftBoundary) {
|
|
16243
|
+
const caretPadding = calculateCaretPadding(caretSizes);
|
|
16244
|
+
const width = tooltipDimensions.width;
|
|
16245
|
+
var leftVal = elementPosition.left - width + (elementPosition.width / 2) + caretPadding;
|
|
16246
|
+
if (leftVal < leftBoundary) {
|
|
16247
|
+
const overflow = leftBoundary - leftVal;
|
|
16248
|
+
const tooltipRight = leftVal + width;
|
|
16249
|
+
if (tooltipRight + overflow > rightBoundary) {
|
|
16250
|
+
return spaceEvenly(leftVal, width);
|
|
16251
|
+
}
|
|
16252
|
+
else {
|
|
16253
|
+
return leftVal + overflow;
|
|
16254
|
+
}
|
|
16255
|
+
}
|
|
16256
|
+
return leftVal;
|
|
16257
|
+
}
|
|
16258
|
+
function calculateCenterBiasPosition(elementPosition, tooltipDimensions, rightBoundary, leftBoundary) {
|
|
16259
|
+
const width = tooltipDimensions.width;
|
|
16260
|
+
var leftVal = elementPosition.left + (elementPosition.width / 2) - (width / 2);
|
|
16261
|
+
let tooltipRight = leftVal + width;
|
|
16262
|
+
if (tooltipRight > rightBoundary) {
|
|
16263
|
+
const overflow = tooltipRight - rightBoundary;
|
|
16264
|
+
leftVal -= overflow;
|
|
16265
|
+
if (leftVal < leftBoundary) {
|
|
16266
|
+
return spaceEvenly(leftVal, width);
|
|
16267
|
+
}
|
|
16268
|
+
}
|
|
16269
|
+
else if (leftVal < leftBoundary) {
|
|
16270
|
+
const overflow = leftBoundary - leftVal;
|
|
16271
|
+
leftVal += overflow;
|
|
16272
|
+
let tooltipRight = leftVal + width;
|
|
16273
|
+
if (tooltipRight > rightBoundary) {
|
|
16274
|
+
return spaceEvenly(leftVal, width);
|
|
16275
|
+
}
|
|
16276
|
+
}
|
|
16277
|
+
return leftVal;
|
|
16278
|
+
}
|
|
16279
|
+
function spaceEvenly(leftVal, width) {
|
|
16280
|
+
const availableLeftSpace = leftVal;
|
|
16281
|
+
const availableRightSpace = window.innerWidth - (leftVal + width);
|
|
16282
|
+
if (availableLeftSpace > availableRightSpace) {
|
|
16283
|
+
return leftVal - (availableLeftSpace - availableRightSpace) / 2;
|
|
16284
|
+
}
|
|
16285
|
+
else if (availableRightSpace > availableLeftSpace) {
|
|
16286
|
+
return leftVal + (availableRightSpace - availableLeftSpace) / 2;
|
|
16287
|
+
}
|
|
16288
|
+
return leftVal;
|
|
16289
|
+
}
|
|
16134
16290
|
function calculateToolTipPositionForLeftRight(tooltipDimensions, screenDimensions, elementPosition, verticalBias) {
|
|
16135
16291
|
var height = tooltipDimensions.height;
|
|
16136
16292
|
var width = tooltipDimensions.width;
|
|
@@ -16161,12 +16317,12 @@ var BuildingBlockTooltips = (function () {
|
|
|
16161
16317
|
}
|
|
16162
16318
|
return tooltipPosition;
|
|
16163
16319
|
}
|
|
16164
|
-
function buildTooltipCaret(tooltipDiv, tooltipDimensions, caretDimensions) {
|
|
16320
|
+
function buildTooltipCaret(tooltipDiv, tooltipDimensions, caretDimensions, elementPos) {
|
|
16165
16321
|
var caretDiv = document.createElement('div');
|
|
16166
16322
|
caretDiv.setAttribute('class', 'pendo-tooltip-caret pendo-tooltip-caret--' + tooltipDimensions.layoutDir);
|
|
16167
16323
|
caretDiv.style.position = 'absolute';
|
|
16168
|
-
caretDiv.style.zIndex =
|
|
16169
|
-
updateCaretStyles(caretDiv, tooltipDimensions, caretDimensions);
|
|
16324
|
+
caretDiv.style.zIndex = TOOLTIP_CONSTANTS.Z_INDEX.CARET;
|
|
16325
|
+
updateCaretStyles(caretDiv, tooltipDimensions, caretDimensions, elementPos);
|
|
16170
16326
|
var guideDiv = tooltipDiv.find('#pendo-guide-container')[0].parentNode;
|
|
16171
16327
|
guideDiv.appendChild(caretDiv);
|
|
16172
16328
|
if (!caretDimensions.borderWidth)
|
|
@@ -16174,35 +16330,20 @@ var BuildingBlockTooltips = (function () {
|
|
|
16174
16330
|
var borderCaret = buildBorderCaret(caretDiv, caretDimensions, tooltipDimensions.layoutDir);
|
|
16175
16331
|
guideDiv.appendChild(borderCaret);
|
|
16176
16332
|
}
|
|
16177
|
-
function updateCaretStyles(caretDiv, tooltipDimensions, caretDimensions) {
|
|
16333
|
+
function updateCaretStyles(caretDiv, tooltipDimensions, caretDimensions, elementPos) {
|
|
16178
16334
|
if (tooltipDimensions.layoutDir === 'top' || tooltipDimensions.layoutDir === 'bottom') {
|
|
16179
|
-
styleTopOrBottomCaret(caretDiv, tooltipDimensions, caretDimensions);
|
|
16335
|
+
styleTopOrBottomCaret(caretDiv, tooltipDimensions, caretDimensions, elementPos);
|
|
16180
16336
|
}
|
|
16181
16337
|
if (tooltipDimensions.layoutDir === 'left' || tooltipDimensions.layoutDir === 'right') {
|
|
16182
16338
|
styleLeftOrRightCaret(caretDiv, tooltipDimensions, caretDimensions);
|
|
16183
16339
|
}
|
|
16184
16340
|
}
|
|
16185
|
-
function styleTopOrBottomCaret(caret, tooltipDimensions, caretDimensions) {
|
|
16186
|
-
var screenDimensions = getScreenDimensions();
|
|
16341
|
+
function styleTopOrBottomCaret(caret, tooltipDimensions, caretDimensions, elementPos) {
|
|
16187
16342
|
caret.style['border-left'] = caretDimensions.width + 'px solid transparent';
|
|
16188
16343
|
caret.style['border-right'] = caretDimensions.width + 'px solid transparent';
|
|
16189
16344
|
caret.style.right = '';
|
|
16190
|
-
|
|
16191
|
-
|
|
16192
|
-
caret.style.left = maxArrowLeft + 'px';
|
|
16193
|
-
tooltipDimensions.left += caretDimensions.offset + caretDimensions.width + caretDimensions.borderWidth;
|
|
16194
|
-
}
|
|
16195
|
-
else if (tooltipDimensions.hbias === RIGHT) {
|
|
16196
|
-
caret.style.left = (caretDimensions.offset + caretDimensions.borderWidth) + 'px';
|
|
16197
|
-
tooltipDimensions.left -= caretDimensions.offset + caretDimensions.width + caretDimensions.borderWidth;
|
|
16198
|
-
if (tooltipDimensions.left + tooltipDimensions.width > screenDimensions.width) {
|
|
16199
|
-
tooltipDimensions.left = tooltipDimensions.left - (tooltipDimensions.left + tooltipDimensions.width - screenDimensions.width);
|
|
16200
|
-
}
|
|
16201
|
-
tooltipDimensions.left = Math.max(0, tooltipDimensions.left);
|
|
16202
|
-
}
|
|
16203
|
-
else { // ASSUME CENTER
|
|
16204
|
-
caret.style.left = (tooltipDimensions.width / 2) - caretDimensions.width + 'px';
|
|
16205
|
-
}
|
|
16345
|
+
const caretOffset = calculateCaretOffset(elementPos, tooltipDimensions, caretDimensions, tooltipDimensions.hbias);
|
|
16346
|
+
caret.style.left = caretOffset + 'px';
|
|
16206
16347
|
// Tooltip is below element, put caret on the top of the tooltip
|
|
16207
16348
|
if (tooltipDimensions.layoutDir === 'bottom') {
|
|
16208
16349
|
caret.style['border-bottom'] = caretDimensions.height + 'px solid ' + caretDimensions.backgroundColor;
|
|
@@ -16227,6 +16368,23 @@ var BuildingBlockTooltips = (function () {
|
|
|
16227
16368
|
}
|
|
16228
16369
|
return caret;
|
|
16229
16370
|
}
|
|
16371
|
+
function calculateCaretOffset(elementPos, tooltipDimensions, caretDimensions, bias) {
|
|
16372
|
+
if (elementPos && elementPos.left) {
|
|
16373
|
+
const elementCenter = elementPos.left + (elementPos.width / 2);
|
|
16374
|
+
return elementCenter - tooltipDimensions.left - caretDimensions.width; // always center the tooltip on the element
|
|
16375
|
+
}
|
|
16376
|
+
else {
|
|
16377
|
+
if (bias === 'left') {
|
|
16378
|
+
return tooltipDimensions.width - caretDimensions.width * 2 - caretDimensions.offset - caretDimensions.borderWidth;
|
|
16379
|
+
}
|
|
16380
|
+
else if (bias === 'right') {
|
|
16381
|
+
return caretDimensions.offset + caretDimensions.borderWidth;
|
|
16382
|
+
}
|
|
16383
|
+
else { // center
|
|
16384
|
+
return (tooltipDimensions.width / 2) - caretDimensions.width;
|
|
16385
|
+
}
|
|
16386
|
+
}
|
|
16387
|
+
}
|
|
16230
16388
|
function styleLeftOrRightCaret(caret, tooltipDimensions, caretDimensions) {
|
|
16231
16389
|
var screenDimensions = getScreenDimensions();
|
|
16232
16390
|
caret.style['border-top'] = caretDimensions.width + 'px solid transparent';
|
|
@@ -16275,7 +16433,7 @@ var BuildingBlockTooltips = (function () {
|
|
|
16275
16433
|
function buildBorderCaret(caret, caretDimensions, tooltipLayoutDirection) {
|
|
16276
16434
|
var borderCaret = caret.cloneNode();
|
|
16277
16435
|
borderCaret.setAttribute('class', 'pendo-tooltip-caret-border');
|
|
16278
|
-
borderCaret.style.zIndex =
|
|
16436
|
+
borderCaret.style.zIndex = TOOLTIP_CONSTANTS.Z_INDEX.BORDER_CARET;
|
|
16279
16437
|
updateBorderCaretStyles(borderCaret, caretDimensions, tooltipLayoutDirection, caret);
|
|
16280
16438
|
return borderCaret;
|
|
16281
16439
|
}
|
|
@@ -16362,7 +16520,7 @@ var BuildingBlockTooltips = (function () {
|
|
|
16362
16520
|
height: parseInt(ttContainer[0].getAttribute('data-caret-height'), 10) || 0,
|
|
16363
16521
|
width: parseInt(ttContainer[0].getAttribute('data-caret-width'), 10) || 0,
|
|
16364
16522
|
backgroundColor: ttContainer[0].style['background-color'],
|
|
16365
|
-
offset:
|
|
16523
|
+
offset: TOOLTIP_CONSTANTS.DEFAULT_CARET_OFFSET,
|
|
16366
16524
|
borderColor: ttContainerStyles.borderColor,
|
|
16367
16525
|
borderWidth: parseInt(ttContainerStyles.borderWidth, 10)
|
|
16368
16526
|
};
|
|
@@ -16371,7 +16529,7 @@ var BuildingBlockTooltips = (function () {
|
|
|
16371
16529
|
var caretDiv = ttdiv.find('.pendo-tooltip-caret')[0];
|
|
16372
16530
|
var borderCaret = ttdiv.find('.pendo-tooltip-caret-border')[0];
|
|
16373
16531
|
if (caretDiv) {
|
|
16374
|
-
updateCaretStyles(caretDiv, tooltipDimensions, caretStyles);
|
|
16532
|
+
updateCaretStyles(caretDiv, tooltipDimensions, caretStyles, elPos);
|
|
16375
16533
|
}
|
|
16376
16534
|
if (borderCaret) {
|
|
16377
16535
|
updateBorderCaretStyles(borderCaret, caretStyles, tooltipDimensions.layoutDir, caretDiv);
|
|
@@ -17853,7 +18011,7 @@ var identify = makeSafe(function (visitor_id, account_id) {
|
|
|
17853
18011
|
});
|
|
17854
18012
|
var isSelfHosted = function () {
|
|
17855
18013
|
var scripts = dom('script');
|
|
17856
|
-
var selfHosted = isSelfHostedUrl(scripts) && (
|
|
18014
|
+
var selfHosted = isSelfHostedUrl(scripts) && !isExtensionAgent();
|
|
17857
18015
|
return selfHosted;
|
|
17858
18016
|
};
|
|
17859
18017
|
var isSelfHostedUrl = function (scripts) {
|
|
@@ -17890,7 +18048,6 @@ function handleIdentifyEvent(event) {
|
|
|
17890
18048
|
ConfigReader.setLocalConfig(options);
|
|
17891
18049
|
store.commit('metadata/setMetadata', options);
|
|
17892
18050
|
}
|
|
17893
|
-
Events.identify.on(handleIdentifyEvent);
|
|
17894
18051
|
|
|
17895
18052
|
/*
|
|
17896
18053
|
* Extension API
|
|
@@ -26527,6 +26684,7 @@ function initIdentityEvents() {
|
|
|
26527
26684
|
}
|
|
26528
26685
|
}
|
|
26529
26686
|
});
|
|
26687
|
+
Events.identify.on(handleIdentifyEvent);
|
|
26530
26688
|
initialized = true;
|
|
26531
26689
|
}
|
|
26532
26690
|
|
|
@@ -26857,6 +27015,7 @@ const initialize = makeSafe(function (options) {
|
|
|
26857
27015
|
// Disable content pre-fetch for guide center
|
|
26858
27016
|
pendo$1.disableGuideCenterContentSearch = options.disableGuideCenterContentSearch;
|
|
26859
27017
|
// Register handlers passed through pendo_options
|
|
27018
|
+
teardownFns.push(forwardInternalEvents(Events));
|
|
26860
27019
|
registerEventHandlers(options);
|
|
26861
27020
|
teardownFns.push(initGuides()); // this is safe. loadGuides actually does the loading.
|
|
26862
27021
|
initIdentityEvents(); // setup identify and meta event listeners
|
|
@@ -27219,6 +27378,9 @@ var BuildingBlockGuides = (function () {
|
|
|
27219
27378
|
}
|
|
27220
27379
|
fixGuideStyleDocument(getGuideAttachPoint(), guideToAppend[0], step.id);
|
|
27221
27380
|
sizeElements(guideToAppend);
|
|
27381
|
+
if (relativeToElement) {
|
|
27382
|
+
BuildingBlockTooltips.patchGuideContainerWidthForResponsiveTooltips(step, guideContainer[0], json);
|
|
27383
|
+
}
|
|
27222
27384
|
// We want to prevent announcement modules from running this code
|
|
27223
27385
|
// because it will cause some elements to resize incorrectly to the
|
|
27224
27386
|
// announcement *module* container instead of the announcement *guide* container
|
|
@@ -28309,25 +28471,28 @@ IntervalJob.prototype.stop = function () {
|
|
|
28309
28471
|
};
|
|
28310
28472
|
|
|
28311
28473
|
var urlFor = ajax.urlFor;
|
|
28474
|
+
// Define the valid attribute-action combinations once
|
|
28475
|
+
var attrActionEnum = {
|
|
28476
|
+
search: ['AllowOnlyKeys', 'ExcludeKeys', 'AddTo', 'Replace', 'Clear'],
|
|
28477
|
+
hash: ['Replace', 'Clear'],
|
|
28478
|
+
pathname: ['Replace', 'Clear', 'AddTo'],
|
|
28479
|
+
hostname: ['Replace'],
|
|
28480
|
+
href: ['Replace', 'ForceSecure'],
|
|
28481
|
+
protocol: ['ForceSecure']
|
|
28482
|
+
};
|
|
28312
28483
|
function UrlAttrTransform(attr, action, data) {
|
|
28313
|
-
var attrActionEnum = {
|
|
28314
|
-
search: ['AllowOnlyKeys', 'ExcludeKeys', 'AddTo', 'Replace', 'Clear'],
|
|
28315
|
-
hash: ['Replace', 'Clear'],
|
|
28316
|
-
pathname: ['Replace'],
|
|
28317
|
-
hostname: ['Replace'],
|
|
28318
|
-
href: ['Replace', 'ForceSecure'],
|
|
28319
|
-
protocol: ['ForceSecure']
|
|
28320
|
-
};
|
|
28321
28484
|
if (_.isObject(attr)) {
|
|
28322
28485
|
action = attr.action;
|
|
28323
28486
|
data = attr.data;
|
|
28324
28487
|
attr = attr.attr;
|
|
28325
28488
|
}
|
|
28326
28489
|
if (!attrActionEnum[attr]) {
|
|
28327
|
-
|
|
28490
|
+
var validAttrs = _.keys(attrActionEnum).join(', ');
|
|
28491
|
+
throw new Error('Invalid URL attribute type: "' + attr + '". Valid attributes are: ' + validAttrs + '. Example: {attr: "search", action: "AddTo", data: {key: "value"}}');
|
|
28328
28492
|
}
|
|
28329
28493
|
if (!_.contains(attrActionEnum[attr], action)) {
|
|
28330
|
-
|
|
28494
|
+
var validActions = attrActionEnum[attr].join(', ');
|
|
28495
|
+
throw new Error('Invalid transform action: "' + action + '" for attribute "' + attr + '". Valid actions for "' + attr + '" are: ' + validActions + '. Example: {attr: "' + attr + '", action: "' + attrActionEnum[attr][0] + '", data: ...}');
|
|
28331
28496
|
}
|
|
28332
28497
|
this.attr = attr;
|
|
28333
28498
|
this.action = action;
|
|
@@ -28353,11 +28518,36 @@ UrlAttrTransform.prototype.applyToURL = function (url) {
|
|
|
28353
28518
|
if (_.isFunction(data)) {
|
|
28354
28519
|
data = data(url[attr], url);
|
|
28355
28520
|
}
|
|
28521
|
+
// AddTo only works for search and pathname attributes; otherwise, do nothing
|
|
28522
|
+
if (attr !== 'search' && attr !== 'pathname') {
|
|
28523
|
+
return url;
|
|
28524
|
+
}
|
|
28525
|
+
if (attr === 'pathname') {
|
|
28526
|
+
// Ensure pathname starts with '/' and append the new segment
|
|
28527
|
+
var currentPath = url.pathname;
|
|
28528
|
+
var newSegment = data;
|
|
28529
|
+
if (!newSegment.startsWith('/')) {
|
|
28530
|
+
newSegment = '/' + newSegment;
|
|
28531
|
+
}
|
|
28532
|
+
if (currentPath.endsWith('/')) {
|
|
28533
|
+
url.pathname = currentPath + newSegment.substring(1);
|
|
28534
|
+
}
|
|
28535
|
+
else {
|
|
28536
|
+
url.pathname = currentPath + newSegment;
|
|
28537
|
+
}
|
|
28538
|
+
return url;
|
|
28539
|
+
}
|
|
28540
|
+
// For search attribute, use the existing urlFor logic
|
|
28356
28541
|
var href = url.href;
|
|
28357
28542
|
return new URL(urlFor(href, data));
|
|
28358
28543
|
},
|
|
28359
28544
|
Clear(url, attr) {
|
|
28360
|
-
|
|
28545
|
+
if (attr === 'pathname') {
|
|
28546
|
+
url.pathname = '/';
|
|
28547
|
+
}
|
|
28548
|
+
else {
|
|
28549
|
+
url[attr] = '';
|
|
28550
|
+
}
|
|
28361
28551
|
return url;
|
|
28362
28552
|
},
|
|
28363
28553
|
Replace(url, attr, data) {
|
|
@@ -28389,7 +28579,67 @@ UrlAttrTransform.fromJSON = function (obj) {
|
|
|
28389
28579
|
if (obj instanceof UrlAttrTransform) {
|
|
28390
28580
|
return obj;
|
|
28391
28581
|
}
|
|
28392
|
-
|
|
28582
|
+
// Validate input is an object
|
|
28583
|
+
if (!_.isObject(obj)) {
|
|
28584
|
+
throw new Error('UrlAttrTransform.fromJSON expects an object. Received: ' + typeof obj + '. Example: {attr: "search", action: "AddTo", data: {key: "value"}}');
|
|
28585
|
+
}
|
|
28586
|
+
// Validate required properties
|
|
28587
|
+
if (!obj.attr) {
|
|
28588
|
+
var allValidAttrs = _.keys(attrActionEnum).join(', ');
|
|
28589
|
+
throw new Error('UrlAttrTransform is missing required "attr" property. Valid attributes are: ' + allValidAttrs + '. Example: {attr: "search", action: "AddTo", data: {key: "value"}}');
|
|
28590
|
+
}
|
|
28591
|
+
if (!obj.action) {
|
|
28592
|
+
var attrValidActions = attrActionEnum[obj.attr] ? attrActionEnum[obj.attr].join(', ') : 'AllowOnlyKeys, ExcludeKeys, AddTo, Replace, Clear';
|
|
28593
|
+
throw new Error('UrlAttrTransform is missing required "action" property. Valid actions depend on the attribute. For "' + obj.attr + '" attribute, valid actions are: ' + attrValidActions + '. Example: {attr: "' + obj.attr + '", action: "AddTo", data: {key: "value"}}');
|
|
28594
|
+
}
|
|
28595
|
+
// Validate attribute and action combination
|
|
28596
|
+
if (!attrActionEnum[obj.attr]) {
|
|
28597
|
+
var validAttrs = _.keys(attrActionEnum).join(', ');
|
|
28598
|
+
throw new Error('Invalid attribute "' + obj.attr + '". Valid attributes are: ' + validAttrs + '. Example: {attr: "search", action: "AddTo", data: {key: "value"}}');
|
|
28599
|
+
}
|
|
28600
|
+
if (!_.contains(attrActionEnum[obj.attr], obj.action)) {
|
|
28601
|
+
var validActions = attrActionEnum[obj.attr].join(', ');
|
|
28602
|
+
throw new Error('Invalid action "' + obj.action + '" for attribute "' + obj.attr + '". Valid actions for "' + obj.attr + '" are: ' + validActions + '. Example: {attr: "' + obj.attr + '", action: "' + attrActionEnum[obj.attr][0] + '", data: ...}');
|
|
28603
|
+
}
|
|
28604
|
+
// Validate data property for actions that require it
|
|
28605
|
+
var actionsRequiringData = ['AllowOnlyKeys', 'ExcludeKeys', 'AddTo', 'Replace'];
|
|
28606
|
+
if (_.contains(actionsRequiringData, obj.action) && obj.data === undefined) {
|
|
28607
|
+
var dataExample = obj.action === 'Replace' ? '"newValue"'
|
|
28608
|
+
: (obj.action === 'AddTo' ? '{key1: "value1"}' : '["key1", "key2"]');
|
|
28609
|
+
throw new Error('Action "' + obj.action + '" requires a "data" property. Example: {attr: "' + obj.attr + '", action: "' + obj.action + '", data: ' + dataExample + '}');
|
|
28610
|
+
}
|
|
28611
|
+
// Validate data types for specific actions
|
|
28612
|
+
if (obj.action === 'AllowOnlyKeys' || obj.action === 'ExcludeKeys') {
|
|
28613
|
+
if (!_.isArray(obj.data)) {
|
|
28614
|
+
throw new Error('Action "' + obj.action + '" requires "data" to be an array of strings. Example: {attr: "' + obj.attr + '", action: "' + obj.action + '", data: ["key1", "key2"]}');
|
|
28615
|
+
}
|
|
28616
|
+
}
|
|
28617
|
+
if (obj.action === 'AddTo') {
|
|
28618
|
+
if (obj.attr === 'pathname') {
|
|
28619
|
+
// For pathname, data can be a string, object, or function
|
|
28620
|
+
if (!_.isString(obj.data) && !_.isObject(obj.data) && !_.isFunction(obj.data)) {
|
|
28621
|
+
throw new Error('Action "AddTo" for pathname requires "data" to be a string, object, or function. Example: {attr: "pathname", action: "AddTo", data: "additional/segment"}');
|
|
28622
|
+
}
|
|
28623
|
+
}
|
|
28624
|
+
else {
|
|
28625
|
+
// For other attributes (like search), data must be an object or function
|
|
28626
|
+
if (!_.isObject(obj.data) && !_.isFunction(obj.data)) {
|
|
28627
|
+
throw new Error('Action "AddTo" requires "data" to be an object or function. Example: {attr: "search", action: "AddTo", data: {key1: "value1", key2: "value2"}}');
|
|
28628
|
+
}
|
|
28629
|
+
}
|
|
28630
|
+
}
|
|
28631
|
+
try {
|
|
28632
|
+
return new UrlAttrTransform(obj.attr, obj.action, obj.data);
|
|
28633
|
+
}
|
|
28634
|
+
catch (error) {
|
|
28635
|
+
// If it's already a detailed error from our validation, re-throw it
|
|
28636
|
+
if (error.message.includes('Invalid attribute') || error.message.includes('Invalid action') ||
|
|
28637
|
+
error.message.includes('requires') || error.message.includes('expects')) {
|
|
28638
|
+
throw error;
|
|
28639
|
+
}
|
|
28640
|
+
// Otherwise, wrap the original error with context
|
|
28641
|
+
throw new Error('Failed to create UrlAttrTransform: ' + error.message + '. Transform object: ' + JSON.stringify(obj));
|
|
28642
|
+
}
|
|
28393
28643
|
};
|
|
28394
28644
|
|
|
28395
28645
|
function isURL(u) {
|
|
@@ -35573,7 +35823,7 @@ const EventProperties = (function () {
|
|
|
35573
35823
|
return;
|
|
35574
35824
|
}
|
|
35575
35825
|
var value = collectEventProperty(ep);
|
|
35576
|
-
if (value) {
|
|
35826
|
+
if (doesExist(value)) {
|
|
35577
35827
|
result['_pendo_' + ep.name] = value;
|
|
35578
35828
|
}
|
|
35579
35829
|
}
|
|
@@ -36390,7 +36640,7 @@ const EmbeddedGuides = (function () {
|
|
|
36390
36640
|
_ = globalPendo._;
|
|
36391
36641
|
exportPublicEmbeddedGuideApi(pendo);
|
|
36392
36642
|
pluginApi.Events.on('deliverablesLoaded', clearEmbeddedGuides);
|
|
36393
|
-
pluginApi.Events.on('guideLoopStopped',
|
|
36643
|
+
pluginApi.Events.on('guideLoopStopped', onGuidesStopped);
|
|
36394
36644
|
pluginApi.Events.on('guideListChanged', initializeEmbeddedGuides);
|
|
36395
36645
|
pluginApi.Events.on('urlChanged', setForceShowFirstStepFlags);
|
|
36396
36646
|
pluginApi.GuideLoop.addUpdatePhase(processEmbeddedGuides);
|
|
@@ -36401,7 +36651,7 @@ const EmbeddedGuides = (function () {
|
|
|
36401
36651
|
function teardown() {
|
|
36402
36652
|
clearEmbeddedGuides();
|
|
36403
36653
|
pluginApi.Events.off('deliverablesLoaded', clearEmbeddedGuides);
|
|
36404
|
-
pluginApi.Events.off('guideLoopStopped',
|
|
36654
|
+
pluginApi.Events.off('guideLoopStopped', onGuidesStopped);
|
|
36405
36655
|
pluginApi.Events.off('guideListChanged', initializeEmbeddedGuides);
|
|
36406
36656
|
pluginApi.Events.off('urlChanged', setForceShowFirstStepFlags);
|
|
36407
36657
|
pluginApi.GuideLoop.removeUpdatePhase(processEmbeddedGuides);
|
|
@@ -36411,6 +36661,14 @@ const EmbeddedGuides = (function () {
|
|
|
36411
36661
|
this.removeResizeEvent();
|
|
36412
36662
|
_oldEmbeddedGuides.length = 0;
|
|
36413
36663
|
}
|
|
36664
|
+
function onGuidesStopped() {
|
|
36665
|
+
// The guideLoopStopped event sometimes is sent when the guide loop is restarted, for example when a guide is advanced.
|
|
36666
|
+
// Do not hide embedded guides in these cases.
|
|
36667
|
+
// The delayGuides flag is set when guides are manually stopped, and unset when guides are manually started.
|
|
36668
|
+
if (pluginApi.ConfigReader.get('delayGuides')) {
|
|
36669
|
+
hideAllEmbeddedGuides();
|
|
36670
|
+
}
|
|
36671
|
+
}
|
|
36414
36672
|
function processEmbeddedGuides() {
|
|
36415
36673
|
_.forEach(embeddedGuides, function (guide) {
|
|
36416
36674
|
guide.process();
|
|
@@ -37965,6 +38223,9 @@ function stubSnippetMethods(pendo) {
|
|
|
37965
38223
|
};
|
|
37966
38224
|
});
|
|
37967
38225
|
}
|
|
38226
|
+
function isConfiguredForMV3(config) {
|
|
38227
|
+
return config && config.useAssetHostForDesigner;
|
|
38228
|
+
}
|
|
37968
38229
|
function initAgent(pendo, PendoConfig) {
|
|
37969
38230
|
setPendoConfig(PendoConfig);
|
|
37970
38231
|
overwriteBuiltConfigWithPendoConfig();
|
|
@@ -37972,6 +38233,9 @@ function initAgent(pendo, PendoConfig) {
|
|
|
37972
38233
|
return false;
|
|
37973
38234
|
if (pendo && pendo.VERSION)
|
|
37974
38235
|
return false;
|
|
38236
|
+
if (sniffer.isChromeExtension && !isConfiguredForMV3(PendoConfig)) {
|
|
38237
|
+
console.warn('Pendo Agent detected running in a Chrome extension with setup that is incompatible with manifest V3. Please follow the linked instructions to maintain manifest V3 compatibility: https://www.npmjs.com/package/@pendo/agent#manifest-v3-extensions');
|
|
38238
|
+
}
|
|
37975
38239
|
if (ConfigReader.get('disablePendo')) {
|
|
37976
38240
|
stubSnippetMethods(pendo);
|
|
37977
38241
|
return false;
|
|
@@ -40882,8 +41146,8 @@ function stringifyStylesheet(s2) {
|
|
|
40882
41146
|
return null;
|
|
40883
41147
|
}
|
|
40884
41148
|
let sheetHref = s2.href;
|
|
40885
|
-
if (!sheetHref && s2.ownerNode
|
|
40886
|
-
sheetHref = s2.ownerNode.
|
|
41149
|
+
if (!sheetHref && s2.ownerNode) {
|
|
41150
|
+
sheetHref = s2.ownerNode.baseURI;
|
|
40887
41151
|
}
|
|
40888
41152
|
const stringifiedRules = Array.from(
|
|
40889
41153
|
rules2,
|