@pendo/agent 2.306.1 → 2.308.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/README.md +27 -27
- package/bin/cli.js +11 -8
- package/dist/dom.esm.js +80 -12
- package/dist/pendo.debugger.min.js +1 -1
- package/dist/pendo.module.js +339 -119
- package/dist/pendo.module.min.js +10 -10
- package/dist/pendo.preview.min.js +3 -3
- package/dist/servers.json +7 -7
- package/package.json +1 -1
package/dist/pendo.module.js
CHANGED
|
@@ -2789,19 +2789,21 @@ var ConfigReader = (function () {
|
|
|
2789
2789
|
function initializeOptions() {
|
|
2790
2790
|
// Core
|
|
2791
2791
|
/**
|
|
2792
|
-
* When included, all analytics events will be sent to each of the
|
|
2793
|
-
* only sent to the primary
|
|
2792
|
+
* Formerly `additionalApiKeys`. When included, all analytics events will be sent to each of the public app IDs in the list (guide events are
|
|
2793
|
+
* only sent to the primary public app ID). This will only function if there are no `additionalPublicAppIds` set on
|
|
2794
2794
|
* the configuration included in the downloaded Agent.
|
|
2795
2795
|
*
|
|
2796
2796
|
* @access public
|
|
2797
2797
|
* @category Config/Core
|
|
2798
|
-
* @name
|
|
2798
|
+
* @name additionalPublicAppIds
|
|
2799
2799
|
* @default []
|
|
2800
2800
|
* @type {string[]}
|
|
2801
2801
|
*/
|
|
2802
|
+
addOption('additionalPublicAppIds', [PENDO_CONFIG_SRC, SNIPPET_SRC]);
|
|
2802
2803
|
addOption('additionalApiKeys', [PENDO_CONFIG_SRC, SNIPPET_SRC]);
|
|
2803
2804
|
addOption('allowedOriginServers');
|
|
2804
2805
|
addOption('allowedOriginServerHashes');
|
|
2806
|
+
addOption('allowMixedApplicationFrames', [SNIPPET_SRC, PENDO_CONFIG_SRC], true);
|
|
2805
2807
|
addOption('allowMixedApiKeyFrames', [SNIPPET_SRC, PENDO_CONFIG_SRC], true);
|
|
2806
2808
|
/**
|
|
2807
2809
|
* A function that returns either an array of strings or an object to decorate the url for events.
|
|
@@ -2815,15 +2817,16 @@ var ConfigReader = (function () {
|
|
|
2815
2817
|
*/
|
|
2816
2818
|
addOption('annotateUrl', [SNIPPET_SRC]);
|
|
2817
2819
|
/**
|
|
2818
|
-
* A primary
|
|
2820
|
+
* Formerly `apiKey`. A primary public app ID to send data to from the Agent. This will only function if there is no `publicAppId` set
|
|
2819
2821
|
* on the configuration included in the downloaded Agent.
|
|
2820
2822
|
*
|
|
2821
2823
|
* @access public
|
|
2822
2824
|
* @category Config/Core
|
|
2823
|
-
* @name
|
|
2825
|
+
* @name publicAppId
|
|
2824
2826
|
* @default undefined
|
|
2825
2827
|
* @type {string}
|
|
2826
2828
|
*/
|
|
2829
|
+
addOption('publicAppId', [PENDO_CONFIG_SRC, SNIPPET_SRC]);
|
|
2827
2830
|
addOption('apiKey', [PENDO_CONFIG_SRC, SNIPPET_SRC]);
|
|
2828
2831
|
addOption('assetHost', [SNIPPET_SRC, PENDO_CONFIG_SRC]);
|
|
2829
2832
|
/**
|
|
@@ -3461,18 +3464,19 @@ var ConfigReader = (function () {
|
|
|
3461
3464
|
*/
|
|
3462
3465
|
addOption('inlineStyleNonce', [SNIPPET_SRC]);
|
|
3463
3466
|
/**
|
|
3464
|
-
* Specify a preferred
|
|
3465
|
-
* guide display. In installations with more than 2
|
|
3466
|
-
* list (e.g. `
|
|
3467
|
-
* or only one frame should specify the
|
|
3467
|
+
* Formerly `leaderKey` Specify a preferred publicAppId to lead the multi-application iframe installation to make decisions about automatic
|
|
3468
|
+
* guide display. In installations with more than 2 publicAppIds, the leaderApplication can be specified as a priority
|
|
3469
|
+
* list (e.g. `leaderApplication: ['key1', 'key2', ...]`). Either all frames must agree on the leaderApplication setting,
|
|
3470
|
+
* or only one frame should specify the leaderApplication. If neither of these conditions are met, the default leader
|
|
3468
3471
|
* determination logic (top frame or earliest to join) will be used.
|
|
3469
3472
|
*
|
|
3470
3473
|
* @access public
|
|
3471
3474
|
* @category Config/Guides
|
|
3472
|
-
* @name
|
|
3475
|
+
* @name leaderApplication
|
|
3473
3476
|
* @default []
|
|
3474
3477
|
* @type {string[]}
|
|
3475
3478
|
*/
|
|
3479
|
+
addOption('leaderApplication', [SNIPPET_SRC, PENDO_CONFIG_SRC], []);
|
|
3476
3480
|
addOption('leaderKey', [SNIPPET_SRC, PENDO_CONFIG_SRC], []);
|
|
3477
3481
|
/**
|
|
3478
3482
|
* If `true`, custom code blocks in building block guides will not be allowed to run. Also, classic guides
|
|
@@ -3533,6 +3537,8 @@ var ConfigReader = (function () {
|
|
|
3533
3537
|
addOption('designerAgentPluginsLoader', [PENDO_CONFIG_SRC, SNIPPET_SRC]);
|
|
3534
3538
|
addOption('guideContentLoader', [PENDO_CONFIG_SRC]);
|
|
3535
3539
|
addOption('trainingPartner');
|
|
3540
|
+
addOption('oemAccountId', [SNIPPET_SRC]);
|
|
3541
|
+
addOption('whiteLabelSettings', [PENDO_CONFIG_SRC]);
|
|
3536
3542
|
// Frustration
|
|
3537
3543
|
addOption('errorClickLogging', [PENDO_CONFIG_SRC], false);
|
|
3538
3544
|
// Embedded Guides
|
|
@@ -3541,6 +3547,7 @@ var ConfigReader = (function () {
|
|
|
3541
3547
|
addOption('formValidation', [PENDO_CONFIG_SRC], false);
|
|
3542
3548
|
// Performance Metrics
|
|
3543
3549
|
addOption('performanceMetricsEnabled', [SNIPPET_SRC, PENDO_CONFIG_SRC], true);
|
|
3550
|
+
addOption('performanceMetricsSampleRate', [SNIPPET_SRC, PENDO_CONFIG_SRC], 0);
|
|
3544
3551
|
}
|
|
3545
3552
|
initializeOptions();
|
|
3546
3553
|
var sourceGetters = {};
|
|
@@ -3905,16 +3912,16 @@ let SERVER = '';
|
|
|
3905
3912
|
let ASSET_HOST = '';
|
|
3906
3913
|
let ASSET_PATH = '';
|
|
3907
3914
|
let DESIGNER_SERVER = '';
|
|
3908
|
-
let VERSION = '2.
|
|
3909
|
-
let PACKAGE_VERSION = '2.
|
|
3915
|
+
let VERSION = '2.308.0_';
|
|
3916
|
+
let PACKAGE_VERSION = '2.308.0';
|
|
3910
3917
|
let LOADER = 'xhr';
|
|
3911
3918
|
/* eslint-enable agent-eslint-rules/no-gulp-env-references */
|
|
3912
3919
|
/**
|
|
3913
|
-
* Returns current version of the
|
|
3920
|
+
* Returns current version of the Pendo Web SDK as a string. Also directly accessible at `pendo.VERSION`.
|
|
3914
3921
|
*
|
|
3915
3922
|
* @access public
|
|
3916
|
-
* @category
|
|
3917
|
-
* @returns {string}
|
|
3923
|
+
* @category Core
|
|
3924
|
+
* @returns {string} web SDK version
|
|
3918
3925
|
* @example
|
|
3919
3926
|
* pendo.getVersion() => '2.150.0'
|
|
3920
3927
|
*/
|
|
@@ -5935,7 +5942,7 @@ function get_visitor_id_public() {
|
|
|
5935
5942
|
return get_visitor_id() || generate_anonymous_visitor_id();
|
|
5936
5943
|
}
|
|
5937
5944
|
/**
|
|
5938
|
-
* Sets visitor id for the
|
|
5945
|
+
* Sets visitor id for the web SDK. Requires a valid visitor id string. This will not change
|
|
5939
5946
|
* or clear existing visitor metadata set.
|
|
5940
5947
|
*
|
|
5941
5948
|
* @access public
|
|
@@ -5978,7 +5985,7 @@ var get_account_id = function () {
|
|
|
5978
5985
|
return pendo$1.accountId;
|
|
5979
5986
|
};
|
|
5980
5987
|
/**
|
|
5981
|
-
* Sets account id for the
|
|
5988
|
+
* Sets account id for the web SDK without changing existing metadata. However,
|
|
5982
5989
|
* An invalid account id or an explicit `null` value will clear the current account id
|
|
5983
5990
|
* and account metadata.
|
|
5984
5991
|
*
|
|
@@ -9552,7 +9559,7 @@ var objectToQueryString = function (obj) {
|
|
|
9552
9559
|
}, '');
|
|
9553
9560
|
};
|
|
9554
9561
|
/**
|
|
9555
|
-
* URL getter that will return the URL that will be used by the
|
|
9562
|
+
* URL getter that will return the URL that will be used by the web SDK to describe all data events
|
|
9556
9563
|
* collected for this app and for Guide requests. This URL can differ from the browser's URL based on
|
|
9557
9564
|
* customizations made by the host application. The URL customizations can be learned about [here](https://agent.pendo.io/advanced/location).
|
|
9558
9565
|
*
|
|
@@ -9624,6 +9631,23 @@ function treatAsAdoptPartner() {
|
|
|
9624
9631
|
// but the agent mechanisms should function identically (at least for now)
|
|
9625
9632
|
return ConfigReader.get('trainingPartner', false) || adoptAnalyticsForwarding;
|
|
9626
9633
|
}
|
|
9634
|
+
/**
|
|
9635
|
+
* Adds account ID parameters for adopt partner requests
|
|
9636
|
+
* Note: Caller should check treatAsAdoptPartner() before calling this function
|
|
9637
|
+
* @param {Object} params - Object to add parameters to (queryString, params, etc.)
|
|
9638
|
+
* @param {string} accountId - Account ID to use for 'acc' parameter
|
|
9639
|
+
* @param {string} [oemAccountId] - Optional OEM account ID, should take priority over accountId
|
|
9640
|
+
* @returns {Object} The params object with account parameters added
|
|
9641
|
+
*/
|
|
9642
|
+
function addAccountIdParams(params, accountId, oemAccountId) {
|
|
9643
|
+
if (oemAccountId) {
|
|
9644
|
+
params.acc = base64EncodeString(oemAccountId);
|
|
9645
|
+
}
|
|
9646
|
+
else if (accountId && accountId !== 'ACCOUNT-UNIQUE-ID') {
|
|
9647
|
+
params.acc = base64EncodeString(accountId);
|
|
9648
|
+
}
|
|
9649
|
+
return params;
|
|
9650
|
+
}
|
|
9627
9651
|
|
|
9628
9652
|
// other node types can be read about here:
|
|
9629
9653
|
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
|
|
@@ -9723,6 +9747,11 @@ function getAbsolutePosition(element, parentElement, _win) {
|
|
|
9723
9747
|
var terminalParent = isOffsetParent(parentElement) ? parentElement : getOffsetParent(parentElement, _win);
|
|
9724
9748
|
var parentRect = terminalParent ? getScreenPosition(terminalParent) : { top: 0, left: 0 };
|
|
9725
9749
|
var elemRect = getScreenPosition(element);
|
|
9750
|
+
const invertedMatrix2d = calculateInverseTransformMatrix2d(terminalParent);
|
|
9751
|
+
if (invertedMatrix2d) {
|
|
9752
|
+
parentRect = applyMatrix2dRect(invertedMatrix2d, parentRect);
|
|
9753
|
+
elemRect = applyMatrix2dRect(invertedMatrix2d, elemRect);
|
|
9754
|
+
}
|
|
9726
9755
|
var elementPosition = {
|
|
9727
9756
|
top: elemRect.top - parentRect.top,
|
|
9728
9757
|
left: elemRect.left - parentRect.left,
|
|
@@ -9769,6 +9798,59 @@ function getScreenPosition(element) {
|
|
|
9769
9798
|
height: rect.height || Math.abs(rect.bottom - rect.top)
|
|
9770
9799
|
};
|
|
9771
9800
|
}
|
|
9801
|
+
function calculateInverseTransformMatrix2d(element) {
|
|
9802
|
+
if (!element)
|
|
9803
|
+
return;
|
|
9804
|
+
const computedStyle = getComputedStyle_safe(element);
|
|
9805
|
+
const matrix2d = parseCssMatrix(computedStyle.transform);
|
|
9806
|
+
if (matrix2d && /^0px\s+0px/.test(computedStyle.transformOrigin)) {
|
|
9807
|
+
// only consider 2D tranforms that have a computed origin of top left
|
|
9808
|
+
return invertMatrix2d(matrix2d);
|
|
9809
|
+
}
|
|
9810
|
+
}
|
|
9811
|
+
function parseCssMatrix(cssMatrix) {
|
|
9812
|
+
if (!/^matrix\(/.test(cssMatrix))
|
|
9813
|
+
return;
|
|
9814
|
+
return cssMatrix.split(/\(|,|\)/).slice(1, -1).map((v) => parseFloat(v));
|
|
9815
|
+
}
|
|
9816
|
+
function invertMatrix2d([a, b, c, d, e, f]) {
|
|
9817
|
+
const determinant = a * d - b * c;
|
|
9818
|
+
// Matrix is not invertible if determinant is 0
|
|
9819
|
+
if (determinant === 0) {
|
|
9820
|
+
return null;
|
|
9821
|
+
}
|
|
9822
|
+
// Invert the 2D matrix
|
|
9823
|
+
// | a c e |
|
|
9824
|
+
// | b d f |
|
|
9825
|
+
// | 0 0 1 |
|
|
9826
|
+
return [
|
|
9827
|
+
d / determinant,
|
|
9828
|
+
-b / determinant,
|
|
9829
|
+
-c / determinant,
|
|
9830
|
+
a / determinant,
|
|
9831
|
+
(c * f - d * e) / determinant,
|
|
9832
|
+
(b * e - a * f) / determinant
|
|
9833
|
+
];
|
|
9834
|
+
}
|
|
9835
|
+
function applyMatrix2d([a, b, c, d, e, f], [x, y]) {
|
|
9836
|
+
return [
|
|
9837
|
+
a * x + c * y + e,
|
|
9838
|
+
b * x + d * y + f
|
|
9839
|
+
];
|
|
9840
|
+
}
|
|
9841
|
+
function applyMatrix2dRect(matrix2d, rect) {
|
|
9842
|
+
const topLeft = applyMatrix2d(matrix2d, [rect.left, rect.top]);
|
|
9843
|
+
const bottomRight = applyMatrix2d(matrix2d, [rect.right, rect.bottom]);
|
|
9844
|
+
const transformedRect = {
|
|
9845
|
+
top: topLeft[1],
|
|
9846
|
+
left: topLeft[0],
|
|
9847
|
+
bottom: bottomRight[1],
|
|
9848
|
+
right: bottomRight[0]
|
|
9849
|
+
};
|
|
9850
|
+
transformedRect.width = transformedRect.right - transformedRect.left;
|
|
9851
|
+
transformedRect.height = transformedRect.bottom - transformedRect.top;
|
|
9852
|
+
return transformedRect;
|
|
9853
|
+
}
|
|
9772
9854
|
|
|
9773
9855
|
function getPendoCore() {
|
|
9774
9856
|
var pendoCoreValue = ConfigReader.get('pendoCore');
|
|
@@ -9846,7 +9928,7 @@ function writeErrorPOST(msg) {
|
|
|
9846
9928
|
*/
|
|
9847
9929
|
function writeMetricsPOST(payload) {
|
|
9848
9930
|
try {
|
|
9849
|
-
const url =
|
|
9931
|
+
const url = buildBaseDataUrl('metrics', pendo$1.apiKey, { v: VERSION });
|
|
9850
9932
|
log.debug(`Sending ${JSON.stringify(payload)} to ${url} using ${fetchKeepalive.supported() ? 'fetch' : 'xhr'}`);
|
|
9851
9933
|
if (fetchKeepalive.supported()) {
|
|
9852
9934
|
fetch(url, {
|
|
@@ -9912,14 +9994,14 @@ var locked = false;
|
|
|
9912
9994
|
* @category Events
|
|
9913
9995
|
* @example
|
|
9914
9996
|
* $ pendo.stopSendingEvents()
|
|
9915
|
-
* > Pendo
|
|
9997
|
+
* > Pendo Web SDK locked. No more events will be written.
|
|
9916
9998
|
*/
|
|
9917
9999
|
var lockEvents = function () {
|
|
9918
10000
|
var fireEvent = isUnlocked();
|
|
9919
10001
|
locked = true;
|
|
9920
10002
|
if (fireEvent)
|
|
9921
10003
|
Events['transmit:locked'].trigger();
|
|
9922
|
-
return 'Pendo
|
|
10004
|
+
return 'Pendo Web SDK locked. No more events will be written.';
|
|
9923
10005
|
};
|
|
9924
10006
|
/**
|
|
9925
10007
|
* Starts event collection and transmission.
|
|
@@ -9929,14 +10011,14 @@ var lockEvents = function () {
|
|
|
9929
10011
|
* @category Events
|
|
9930
10012
|
* @example
|
|
9931
10013
|
* $ pendo.startSendingEvents()
|
|
9932
|
-
* > Pendo
|
|
10014
|
+
* > Pendo Web SDK unlocked. Events will be written.
|
|
9933
10015
|
*/
|
|
9934
10016
|
var unlockEvents = function () {
|
|
9935
10017
|
var fireEvent = !isUnlocked();
|
|
9936
10018
|
locked = false;
|
|
9937
10019
|
if (fireEvent)
|
|
9938
10020
|
Events['transmit:unlocked'].trigger();
|
|
9939
|
-
return 'Pendo
|
|
10021
|
+
return 'Pendo Web SDK unlocked. Events will be written.';
|
|
9940
10022
|
};
|
|
9941
10023
|
/**
|
|
9942
10024
|
* Returns true if event collection is currently enabled.
|
|
@@ -10796,7 +10878,7 @@ function scrollIntoView(element) {
|
|
|
10796
10878
|
* @class DomQuery
|
|
10797
10879
|
* @type {Element[]}
|
|
10798
10880
|
* @classdesc
|
|
10799
|
-
* Sort of like a diet, caffeine-free jQuery. Wrapper for Sizzle library with additional methods for the Pendo
|
|
10881
|
+
* Sort of like a diet, caffeine-free jQuery. Wrapper for Sizzle library with additional methods for the Pendo Web SDK.
|
|
10800
10882
|
* Use pendo.Sizzle for customer-defined selectors. Augmented Element[] used to query and alter DOM nodes.
|
|
10801
10883
|
*
|
|
10802
10884
|
* @access public
|
|
@@ -12399,8 +12481,11 @@ class PerformanceMonitor {
|
|
|
12399
12481
|
this._markPerformance(INITIALIZE);
|
|
12400
12482
|
this._setDebugging();
|
|
12401
12483
|
Events.debuggerLaunched.on(this._setDebuggingBound);
|
|
12484
|
+
const shouldSend = Math.random() * 100 < ConfigReader.get('performanceMetricsSampleRate');
|
|
12485
|
+
this._setSending(shouldSend);
|
|
12486
|
+
// interval always runs to periodically free memory used by performance api
|
|
12402
12487
|
this.interval = setInterval(() => {
|
|
12403
|
-
this.send();
|
|
12488
|
+
this.send(); // includes call to _clearMarksAndMeasures()
|
|
12404
12489
|
}, PERFORMANCE_SEND_INTERVAL);
|
|
12405
12490
|
return () => {
|
|
12406
12491
|
this.teardown();
|
|
@@ -12437,12 +12522,14 @@ class PerformanceMonitor {
|
|
|
12437
12522
|
return acc;
|
|
12438
12523
|
const entries = performance.getEntriesByName(name);
|
|
12439
12524
|
const value = instrument(entries);
|
|
12440
|
-
|
|
12441
|
-
|
|
12442
|
-
|
|
12443
|
-
|
|
12444
|
-
|
|
12445
|
-
|
|
12525
|
+
if (value > 0) {
|
|
12526
|
+
acc.push({
|
|
12527
|
+
name,
|
|
12528
|
+
type,
|
|
12529
|
+
value,
|
|
12530
|
+
timestamp: Date.now()
|
|
12531
|
+
});
|
|
12532
|
+
}
|
|
12446
12533
|
return acc;
|
|
12447
12534
|
}, []);
|
|
12448
12535
|
this._clearMarksAndMeasures();
|
|
@@ -12783,11 +12870,11 @@ function addSiloParams(options) {
|
|
|
12783
12870
|
};
|
|
12784
12871
|
}
|
|
12785
12872
|
function addAccountIdParamIfAdoptPartner(silo, next) {
|
|
12786
|
-
|
|
12787
|
-
|
|
12788
|
-
|
|
12789
|
-
|
|
12790
|
-
silo.params
|
|
12873
|
+
if (treatAsAdoptPartner()) {
|
|
12874
|
+
var firstEvent = _.first(silo);
|
|
12875
|
+
var accountId = _.get(firstEvent, 'account_id');
|
|
12876
|
+
var oemAccountId = _.get(firstEvent, 'oem_account_id');
|
|
12877
|
+
addAccountIdParams(silo.params || (silo.params = {}), accountId, oemAccountId);
|
|
12791
12878
|
}
|
|
12792
12879
|
next(silo);
|
|
12793
12880
|
}
|
|
@@ -13617,7 +13704,7 @@ var DEBOUNCE_INTERVAL_CHANGE = 5000;
|
|
|
13617
13704
|
var handle_change_event = _.debounce(handle_event, DEBOUNCE_INTERVAL_CHANGE, true);
|
|
13618
13705
|
/*
|
|
13619
13706
|
* Wires up the page for all the different event driven
|
|
13620
|
-
* functions that the
|
|
13707
|
+
* functions that the web SDK cares about.
|
|
13621
13708
|
*
|
|
13622
13709
|
* input: eventlist (Array<string>) names of events
|
|
13623
13710
|
*/
|
|
@@ -13852,7 +13939,7 @@ function interceptPreventDefault(EventConstructor, eventList) {
|
|
|
13852
13939
|
};
|
|
13853
13940
|
}
|
|
13854
13941
|
/**
|
|
13855
|
-
* Pendo
|
|
13942
|
+
* Pendo Web SDK's version of attaching event listeners.
|
|
13856
13943
|
*
|
|
13857
13944
|
* @access public
|
|
13858
13945
|
* @category Events
|
|
@@ -13877,7 +13964,7 @@ function attachEvent(element, evt, fn, useCapture) {
|
|
|
13877
13964
|
});
|
|
13878
13965
|
}
|
|
13879
13966
|
/**
|
|
13880
|
-
* Pendo
|
|
13967
|
+
* Pendo Web SDK's version of detaching event listeners. Callback must be a named function, cannot remove
|
|
13881
13968
|
* anonymous functions.
|
|
13882
13969
|
*
|
|
13883
13970
|
* @access public
|
|
@@ -13920,7 +14007,12 @@ var whenLoadedCall = function (callback, win) {
|
|
|
13920
14007
|
callback();
|
|
13921
14008
|
}
|
|
13922
14009
|
else {
|
|
13923
|
-
return attachEventInternal(win, 'load',
|
|
14010
|
+
return attachEventInternal(win, 'load', function () {
|
|
14011
|
+
// some apps fire "fake" load events APP-139170 (https://github.com/rtCamp/rt-optimizer/blob/main/rt-scripts-optimizer.php#L173)
|
|
14012
|
+
if (document.readyState === 'complete') {
|
|
14013
|
+
callback();
|
|
14014
|
+
}
|
|
14015
|
+
});
|
|
13924
14016
|
}
|
|
13925
14017
|
return _.noop;
|
|
13926
14018
|
};
|
|
@@ -15495,29 +15587,55 @@ function addInlineStyles(config, id, styles, element = document.head) {
|
|
|
15495
15587
|
return styleTag;
|
|
15496
15588
|
}
|
|
15497
15589
|
|
|
15498
|
-
|
|
15590
|
+
const DARK_MODE_ATTR = 'data-pendo-dark-mode';
|
|
15591
|
+
/**
|
|
15592
|
+
* Applies data-pendo-dark-mode attribute for CSS pseudo-styles. Requires step.guideElement.
|
|
15593
|
+
*/
|
|
15594
|
+
function applyDarkModeAttr(step) {
|
|
15595
|
+
if (!step.guideElement)
|
|
15596
|
+
return;
|
|
15597
|
+
const guideContainer = dom('#pendo-guide-container', step.guideElement)[0];
|
|
15598
|
+
if (!guideContainer)
|
|
15599
|
+
return;
|
|
15600
|
+
if (step.isDarkMode) {
|
|
15601
|
+
guideContainer.setAttribute(DARK_MODE_ATTR, '');
|
|
15602
|
+
}
|
|
15603
|
+
else {
|
|
15604
|
+
guideContainer.removeAttribute(DARK_MODE_ATTR);
|
|
15605
|
+
}
|
|
15606
|
+
}
|
|
15607
|
+
/**
|
|
15608
|
+
* Sets step.isDarkMode based on selector. Call before buildNodeFromJSON.
|
|
15609
|
+
*/
|
|
15610
|
+
function detectColorMode(step) {
|
|
15499
15611
|
const darkModeSelector = _.get(step, 'attributes.darkMode.selector', '');
|
|
15500
15612
|
if (!darkModeSelector)
|
|
15501
15613
|
return;
|
|
15502
|
-
// Determine the target dark mode state
|
|
15503
15614
|
let targetDarkMode;
|
|
15504
15615
|
if (pendo$1.designerEnabled && _.has(step, 'attributes.darkMode.override')) {
|
|
15505
|
-
// In designer mode, use the override value
|
|
15506
15616
|
targetDarkMode = step.attributes.darkMode.override;
|
|
15507
15617
|
}
|
|
15508
15618
|
else {
|
|
15509
|
-
// In client mode, detect based on selector
|
|
15510
15619
|
try {
|
|
15511
15620
|
targetDarkMode = pendo$1.Sizzle(darkModeSelector).length > 0;
|
|
15512
15621
|
}
|
|
15513
15622
|
catch (e) {
|
|
15514
|
-
// Invalid selector - default to light mode
|
|
15515
15623
|
targetDarkMode = false;
|
|
15516
15624
|
}
|
|
15517
15625
|
}
|
|
15518
|
-
|
|
15519
|
-
|
|
15520
|
-
|
|
15626
|
+
step.isDarkMode = targetDarkMode;
|
|
15627
|
+
}
|
|
15628
|
+
/**
|
|
15629
|
+
* Syncs color mode for live updates. Detects, applies attribute, and optionally rerenders.
|
|
15630
|
+
*/
|
|
15631
|
+
function syncColorMode(step, rerender = false) {
|
|
15632
|
+
const darkModeSelector = _.get(step, 'attributes.darkMode.selector', '');
|
|
15633
|
+
if (!darkModeSelector)
|
|
15634
|
+
return;
|
|
15635
|
+
const previousMode = step.isDarkMode;
|
|
15636
|
+
detectColorMode(step);
|
|
15637
|
+
if (previousMode !== step.isDarkMode) {
|
|
15638
|
+
applyDarkModeAttr(step);
|
|
15521
15639
|
if (rerender) {
|
|
15522
15640
|
step.hide();
|
|
15523
15641
|
step.show(step.seenReason);
|
|
@@ -16603,7 +16721,6 @@ var BuildingBlockTooltips = (function () {
|
|
|
16603
16721
|
var caretDimensions = {
|
|
16604
16722
|
height: parseInt(containerDomJson.props['data-caret-height'], 10) || 0,
|
|
16605
16723
|
width: parseInt(containerDomJson.props['data-caret-width'], 10) || 0,
|
|
16606
|
-
backgroundColor: containerDomJson.props.style['background-color'],
|
|
16607
16724
|
offset: TOOLTIP_CONSTANTS.DEFAULT_CARET_OFFSET,
|
|
16608
16725
|
borderWidth: 0
|
|
16609
16726
|
};
|
|
@@ -16623,6 +16740,16 @@ var BuildingBlockTooltips = (function () {
|
|
|
16623
16740
|
caretDimensions.borderColor = guideBorderArray[2];
|
|
16624
16741
|
caretDimensions.borderWidth = parseInt(guideBorderArray[0], 10) || 0;
|
|
16625
16742
|
}
|
|
16743
|
+
const lightStyle = _.get(containerDomJson, 'props.style');
|
|
16744
|
+
const darkModeStyle = _.get(containerDomJson, 'darkModeProps.style');
|
|
16745
|
+
const backgroundColor = _.get(lightStyle, 'background-color');
|
|
16746
|
+
const darkModeBackgroundColor = _.get(darkModeStyle, 'background-color');
|
|
16747
|
+
if (step && step.isDarkMode && darkModeBackgroundColor) {
|
|
16748
|
+
caretDimensions.backgroundColor = darkModeBackgroundColor;
|
|
16749
|
+
}
|
|
16750
|
+
else if (backgroundColor) {
|
|
16751
|
+
caretDimensions.backgroundColor = backgroundColor;
|
|
16752
|
+
}
|
|
16626
16753
|
const tooltipSizes = {
|
|
16627
16754
|
width: guideContainer.offsetWidth,
|
|
16628
16755
|
height: guideContainer.offsetHeight,
|
|
@@ -18293,11 +18420,12 @@ function buildNodeFromJSON(json, step, guides) {
|
|
|
18293
18420
|
}
|
|
18294
18421
|
let css = json.css;
|
|
18295
18422
|
if (json.forDarkMode) {
|
|
18296
|
-
|
|
18423
|
+
// Use data attribute on pendo-guide-container as the selector prefix
|
|
18424
|
+
// syncColorMode toggles this attribute, making dark mode styles apply/not apply
|
|
18297
18425
|
css = _.map(css, function (rule) {
|
|
18298
18426
|
return {
|
|
18299
18427
|
styles: rule.styles,
|
|
18300
|
-
selector:
|
|
18428
|
+
selector: `[data-pendo-dark-mode] ${rule.selector}`
|
|
18301
18429
|
};
|
|
18302
18430
|
});
|
|
18303
18431
|
}
|
|
@@ -18650,7 +18778,7 @@ var updateVisitorOptions = function (options = {}) {
|
|
|
18650
18778
|
};
|
|
18651
18779
|
};
|
|
18652
18780
|
/**
|
|
18653
|
-
* Updates metadata object for the Pendo
|
|
18781
|
+
* Updates metadata object for the Pendo Web SDK. Can include visitor and/or account updates, along
|
|
18654
18782
|
* with customer-defined metadata values. Changes to identity information will potentially fire
|
|
18655
18783
|
* identity and metadata events, in turn evaluating guide eligibility for the new user and displaying
|
|
18656
18784
|
* any matching guides automatically.
|
|
@@ -18658,7 +18786,7 @@ var updateVisitorOptions = function (options = {}) {
|
|
|
18658
18786
|
* @access public
|
|
18659
18787
|
* @function
|
|
18660
18788
|
* @category Identity
|
|
18661
|
-
* @param {object} options new metadata to set in the
|
|
18789
|
+
* @param {object} options new metadata to set in the web SDK
|
|
18662
18790
|
* @example
|
|
18663
18791
|
* pendo.updateOptions( { visitor: { "role":"admin" } , account: { "industry":"retail" } });
|
|
18664
18792
|
*/
|
|
@@ -18719,11 +18847,11 @@ var isMetadataBlocked = function () {
|
|
|
18719
18847
|
};
|
|
18720
18848
|
function getMetadata() { return store.getters['metadata/metadata'](); }
|
|
18721
18849
|
/**
|
|
18722
|
-
* Returns all metadata being passed through the
|
|
18850
|
+
* Returns all metadata being passed through the web SDK.
|
|
18723
18851
|
*
|
|
18724
18852
|
* @access public
|
|
18725
18853
|
* @category Identity
|
|
18726
|
-
* @returns {JSON} metadata available to the
|
|
18854
|
+
* @returns {JSON} metadata available to the web SDK
|
|
18727
18855
|
* @example
|
|
18728
18856
|
* pendo.getSerializedMetadata()
|
|
18729
18857
|
*/
|
|
@@ -19123,7 +19251,7 @@ var BuildingBlockResourceCenter = (function () {
|
|
|
19123
19251
|
renderNativeIntegration(integrationProvider);
|
|
19124
19252
|
var step = module.steps[0];
|
|
19125
19253
|
if (step.isDarkMode === undefined) {
|
|
19126
|
-
|
|
19254
|
+
detectColorMode(step);
|
|
19127
19255
|
}
|
|
19128
19256
|
var domJsonToRender = updatePseudoStyleSelectors(step.domJson);
|
|
19129
19257
|
domJsonToRender.props['data-pendo-guide-id'] = module.id;
|
|
@@ -19157,6 +19285,8 @@ var BuildingBlockResourceCenter = (function () {
|
|
|
19157
19285
|
}
|
|
19158
19286
|
step.guideElement = dom(resourceCenterContainer);
|
|
19159
19287
|
step.elements.push(step.guideElement[0]);
|
|
19288
|
+
// Apply data-pendo-dark-mode attribute for CSS pseudo-styles
|
|
19289
|
+
applyDarkModeAttr(step);
|
|
19160
19290
|
// At this point, the RC is in a state where both the module/homeView currently shown and the
|
|
19161
19291
|
// module/homeView we are transitioning to are in the DOM. guideContainer is the module/homeView
|
|
19162
19292
|
// we are transitioning to so we send that to adjustResourceCenterWidth so it's width can be
|
|
@@ -22395,6 +22525,17 @@ function createPreviewBar() {
|
|
|
22395
22525
|
}
|
|
22396
22526
|
var script = document.createElement('script');
|
|
22397
22527
|
script.src = getPreviewModeAssetUrl();
|
|
22528
|
+
script.onload = function () {
|
|
22529
|
+
var whiteLabelSettings = ConfigReader.get('whiteLabelSettings');
|
|
22530
|
+
if (whiteLabelSettings && frame.contentWindow) {
|
|
22531
|
+
frame.contentWindow.postMessage({
|
|
22532
|
+
mutation: 'preview/setWhiteLabelSettings',
|
|
22533
|
+
payload: {
|
|
22534
|
+
whiteLabelSettings
|
|
22535
|
+
}
|
|
22536
|
+
}, location.origin);
|
|
22537
|
+
}
|
|
22538
|
+
};
|
|
22398
22539
|
frame.contentDocument.body.appendChild(script);
|
|
22399
22540
|
frame.contentWindow.ignoreIframeMonitor = true;
|
|
22400
22541
|
};
|
|
@@ -22578,6 +22719,15 @@ function updatePreview(document, activeGuides, lastGuideStepSeen) {
|
|
|
22578
22719
|
hostname: SERVER
|
|
22579
22720
|
}
|
|
22580
22721
|
}, location.origin);
|
|
22722
|
+
var whiteLabelSettings = ConfigReader.get('whiteLabelSettings');
|
|
22723
|
+
if (whiteLabelSettings) {
|
|
22724
|
+
previewFrame.contentWindow.postMessage({
|
|
22725
|
+
mutation: 'preview/setWhiteLabelSettings',
|
|
22726
|
+
payload: {
|
|
22727
|
+
whiteLabelSettings
|
|
22728
|
+
}
|
|
22729
|
+
}, location.origin);
|
|
22730
|
+
}
|
|
22581
22731
|
previewFrame.contentWindow.postMessage({
|
|
22582
22732
|
mutation: 'preview/setGuidePages',
|
|
22583
22733
|
payload: {
|
|
@@ -22928,43 +23078,44 @@ function insertOriginContentHash(originalHash, url, extensionStr, sha256Hash) {
|
|
|
22928
23078
|
}
|
|
22929
23079
|
|
|
22930
23080
|
/**
|
|
22931
|
-
*
|
|
23081
|
+
* Formerly `apiKey`. Public app ID that is associated with the current Pendo installation as a string.
|
|
22932
23082
|
*
|
|
22933
23083
|
* @access public
|
|
22934
|
-
* @name
|
|
23084
|
+
* @name publicAppId
|
|
22935
23085
|
* @type {string}
|
|
22936
|
-
* @category
|
|
23086
|
+
* @category Core
|
|
22937
23087
|
* @example
|
|
22938
|
-
* pendo.
|
|
23088
|
+
* pendo.publicAppId => 'PUBLIC_APP_ID'
|
|
22939
23089
|
*/
|
|
22940
23090
|
/**
|
|
22941
|
-
* Array of additional
|
|
22942
|
-
* the first in this array will be assigned to `pendo.
|
|
23091
|
+
* Formerly `additionalApiKeys`. Array of additional app IDs that are set in the config. If no primary app ID is set,
|
|
23092
|
+
* the first in this array will be assigned to `pendo.publicAppId`.
|
|
22943
23093
|
*
|
|
22944
23094
|
* @access public
|
|
22945
|
-
* @name
|
|
23095
|
+
* @name additionalPublicAppIds
|
|
22946
23096
|
* @type {string[]}
|
|
22947
|
-
* @category
|
|
23097
|
+
* @category Core
|
|
22948
23098
|
* @example
|
|
22949
|
-
* pendo.
|
|
23099
|
+
* pendo.additionalPublicAppIds => ['FIRST_PUBLIC_APP_ID', 'SECOND_PUBLIC_APP_ID']
|
|
22950
23100
|
*/
|
|
22951
23101
|
const Keys = (function () {
|
|
22952
23102
|
let _apiKey = null;
|
|
22953
23103
|
let _additionalApiKeys = [];
|
|
22954
23104
|
const setApiKey = (key) => {
|
|
22955
23105
|
key += '';
|
|
22956
|
-
pendo$1.apiKey = key;
|
|
23106
|
+
pendo$1.apiKey = pendo$1.publicAppId = key;
|
|
22957
23107
|
_apiKey = key;
|
|
22958
23108
|
};
|
|
22959
23109
|
const discoverApiKey = (apiKey) => {
|
|
22960
|
-
apiKey = ConfigReader.get('apiKey', apiKey);
|
|
23110
|
+
apiKey = ConfigReader.get('publicAppId') || ConfigReader.get('apiKey', apiKey);
|
|
22961
23111
|
if (apiKey) {
|
|
22962
23112
|
setApiKey(apiKey);
|
|
22963
23113
|
}
|
|
22964
23114
|
return _apiKey;
|
|
22965
23115
|
};
|
|
22966
23116
|
const discoverAdditionalApiKeys = (additionalApiKeys) => {
|
|
22967
|
-
additionalApiKeys = ConfigReader.get('
|
|
23117
|
+
additionalApiKeys = ConfigReader.get('additionalPublicAppIds') ||
|
|
23118
|
+
ConfigReader.get('additionalApiKeys', additionalApiKeys);
|
|
22968
23119
|
_additionalApiKeys = _.reduce(additionalApiKeys, (arr, key) => {
|
|
22969
23120
|
if (key) {
|
|
22970
23121
|
arr.push(key + '');
|
|
@@ -22972,7 +23123,7 @@ const Keys = (function () {
|
|
|
22972
23123
|
return arr;
|
|
22973
23124
|
}, []);
|
|
22974
23125
|
_additionalApiKeys = [].concat(additionalApiKeys);
|
|
22975
|
-
pendo$1.additionalApiKeys = _additionalApiKeys;
|
|
23126
|
+
pendo$1.additionalApiKeys = pendo$1.additionalPublicAppIds = _additionalApiKeys;
|
|
22976
23127
|
return _additionalApiKeys;
|
|
22977
23128
|
};
|
|
22978
23129
|
return {
|
|
@@ -25765,7 +25916,6 @@ function isGuideRequestPending() {
|
|
|
25765
25916
|
}
|
|
25766
25917
|
var mostRecentGuideRequest;
|
|
25767
25918
|
var loadGuideJs = function (apiKey, params) {
|
|
25768
|
-
var isAdoptPartner = treatAsAdoptPartner();
|
|
25769
25919
|
var guideRequestId = _.uniqueId();
|
|
25770
25920
|
var deferred = q.defer();
|
|
25771
25921
|
mostRecentGuideRequest = {
|
|
@@ -25793,8 +25943,8 @@ var loadGuideJs = function (apiKey, params) {
|
|
|
25793
25943
|
v: VERSION,
|
|
25794
25944
|
ct: (new Date()).getTime()
|
|
25795
25945
|
};
|
|
25796
|
-
if (
|
|
25797
|
-
queryString
|
|
25946
|
+
if (treatAsAdoptPartner()) {
|
|
25947
|
+
addAccountIdParams(queryString, params.accountId, ConfigReader.get('oemAccountId'));
|
|
25798
25948
|
}
|
|
25799
25949
|
if (isDebuggingEnabled()) {
|
|
25800
25950
|
// Include debug info from server
|
|
@@ -25942,7 +26092,7 @@ function shouldLoadGuides(visitorId, callback) {
|
|
|
25942
26092
|
return true;
|
|
25943
26093
|
}
|
|
25944
26094
|
/**
|
|
25945
|
-
* Manually load guides for current visitor and URL. This is typically handled automatically by the
|
|
26095
|
+
* Manually load guides for current visitor and URL. This is typically handled automatically by the web SDK
|
|
25946
26096
|
* whenever the host Application changes its URL. In rare circumstances, a host Application may chose to
|
|
25947
26097
|
* force the load of Guides programmatically. One reason may be in order to get any guides designed for a visitor
|
|
25948
26098
|
* immediately after using a specific part of the Application that doesn't cause a URL change.
|
|
@@ -27332,7 +27482,7 @@ var EventRouter = function () {
|
|
|
27332
27482
|
step.response(_.compact(responses));
|
|
27333
27483
|
}
|
|
27334
27484
|
else {
|
|
27335
|
-
log.info('[
|
|
27485
|
+
log.info('[Pendo Web SDK] Error! Trying to submit a poll response but step does not have response function!');
|
|
27336
27486
|
}
|
|
27337
27487
|
if (actionType !== actionKeys.submitPollAndGoToStep) {
|
|
27338
27488
|
step.advance();
|
|
@@ -27857,7 +28007,8 @@ var initialized$1 = false;
|
|
|
27857
28007
|
const PluginAPI = {
|
|
27858
28008
|
agent: {
|
|
27859
28009
|
getJwtInfoCopy: JWT.get,
|
|
27860
|
-
treatAsAdoptPartner
|
|
28010
|
+
treatAsAdoptPartner,
|
|
28011
|
+
addAccountIdParams
|
|
27861
28012
|
},
|
|
27862
28013
|
agentStorage,
|
|
27863
28014
|
analytics: {
|
|
@@ -28190,14 +28341,14 @@ var ResourceCenterActivity = (function () {
|
|
|
28190
28341
|
})();
|
|
28191
28342
|
|
|
28192
28343
|
/**
|
|
28193
|
-
* Returns boolean representing whether the
|
|
28344
|
+
* Returns boolean representing whether the Pendo Web SDK is fully loaded and has an API key.
|
|
28194
28345
|
*
|
|
28195
28346
|
* @access public
|
|
28196
|
-
* @category
|
|
28347
|
+
* @category Core
|
|
28197
28348
|
* @returns {boolean}
|
|
28198
28349
|
* @example
|
|
28199
28350
|
* if (pendo.isReady()) {
|
|
28200
|
-
* // runs if
|
|
28351
|
+
* // runs if web SDK has fully loaded
|
|
28201
28352
|
* }
|
|
28202
28353
|
*/
|
|
28203
28354
|
const isReady = (pendoObj) => {
|
|
@@ -28391,14 +28542,14 @@ function registerEventHandlers({ events = [] }) {
|
|
|
28391
28542
|
let initializeCounter = 0;
|
|
28392
28543
|
const initializeImmediately = 'initializeImmediately';
|
|
28393
28544
|
/**
|
|
28394
|
-
* Initializes the Pendo
|
|
28395
|
-
* Once the
|
|
28545
|
+
* Initializes the Pendo Web SDK in a browser window. This function only needs to be called once per page load. Any subsequent calls, without first having called `teardown`, will be ignored.
|
|
28546
|
+
* Once the web SDK has been initialized, any updates to identity or metadata should be done using `identify` or `updateOptions`.
|
|
28396
28547
|
*
|
|
28397
28548
|
* @access public
|
|
28398
28549
|
* @function
|
|
28399
|
-
* @category
|
|
28550
|
+
* @category Core
|
|
28400
28551
|
* @name initialize
|
|
28401
|
-
* @param {object} options identity metadata and configuration to initialize
|
|
28552
|
+
* @param {object} options identity metadata and configuration to initialize web SDK
|
|
28402
28553
|
* @see {@link https://support.pendo.io/hc/en-us/articles/360046272771-Developer-s-guide-to-installing-Pendo#what-installation-involves-0-2 | Pendo Installation}
|
|
28403
28554
|
* @example
|
|
28404
28555
|
* pendo.initialize({
|
|
@@ -28434,7 +28585,7 @@ const initialize = makeSafe(function (options) {
|
|
|
28434
28585
|
log.info([
|
|
28435
28586
|
'pendo.initialize only needs to be called once',
|
|
28436
28587
|
isSfdcLightning() ? ' per namespace' : '',
|
|
28437
|
-
'. Use pendo.updateOptions to update metadata after the
|
|
28588
|
+
'. Use pendo.updateOptions to update metadata after the web SDK has initialized.'
|
|
28438
28589
|
].join(''));
|
|
28439
28590
|
}
|
|
28440
28591
|
return;
|
|
@@ -28656,12 +28807,12 @@ function startup(callQueue, autoInitialize, whenLoadedCall) {
|
|
|
28656
28807
|
}
|
|
28657
28808
|
}
|
|
28658
28809
|
/**
|
|
28659
|
-
* Shuts down the
|
|
28660
|
-
* the
|
|
28810
|
+
* Shuts down the web SDK and cleans up all timers and listeners. Upon completion
|
|
28811
|
+
* the web SDK will be able to be re-initialized when needed or cleaned up from
|
|
28661
28812
|
* the window. This will halt all guides and data collection.
|
|
28662
28813
|
*
|
|
28663
28814
|
* @access public
|
|
28664
|
-
* @category
|
|
28815
|
+
* @category Core
|
|
28665
28816
|
* @returns {void}
|
|
28666
28817
|
* @example
|
|
28667
28818
|
* window.pendo.teardown();
|
|
@@ -28831,8 +28982,9 @@ var BuildingBlockGuides = (function () {
|
|
|
28831
28982
|
function renderGuideFromJSON(json, step, guides, options) {
|
|
28832
28983
|
options = options || {};
|
|
28833
28984
|
var guide = step.getGuide();
|
|
28985
|
+
// Set step.isDarkMode before build (used for inline styles, SVGs, dark mode props)
|
|
28834
28986
|
if (step.isDarkMode === undefined) {
|
|
28835
|
-
|
|
28987
|
+
detectColorMode(step);
|
|
28836
28988
|
}
|
|
28837
28989
|
var containerJSON = findGuideContainerJSON(json);
|
|
28838
28990
|
var isResourceCenter = _.get(guide, 'attributes.resourceCenter');
|
|
@@ -28848,6 +29000,8 @@ var BuildingBlockGuides = (function () {
|
|
|
28848
29000
|
var modifiableJSON = unwrapFirefoxObject(json);
|
|
28849
29001
|
var guideToAppend = BuildingBlockGuides.buildNodeFromJSON(modifiableJSON, step, guides);
|
|
28850
29002
|
step.guideElement = guideToAppend;
|
|
29003
|
+
// Apply data-pendo-dark-mode attribute to guide container for CSS pseudo-styles
|
|
29004
|
+
applyDarkModeAttr(step);
|
|
28851
29005
|
var guideContainer = guideToAppend.find('#' + step.containerId);
|
|
28852
29006
|
var verticalAlignmentAttr = 'data-vertical-alignment';
|
|
28853
29007
|
var relativeToElement = guideContainer.attr(verticalAlignmentAttr) === 'Relative to Element';
|
|
@@ -29389,7 +29543,7 @@ var getDefaultActiveContexts = function () {
|
|
|
29389
29543
|
return ac.split(',');
|
|
29390
29544
|
};
|
|
29391
29545
|
/**
|
|
29392
|
-
* Enable
|
|
29546
|
+
* Enable console logging for debugging purposes.
|
|
29393
29547
|
*
|
|
29394
29548
|
* @access public
|
|
29395
29549
|
* @category Debugging
|
|
@@ -29408,7 +29562,7 @@ var enableLogging = function () {
|
|
|
29408
29562
|
return 'logging enabled';
|
|
29409
29563
|
};
|
|
29410
29564
|
/**
|
|
29411
|
-
* Disable
|
|
29565
|
+
* Disable console logging for debugging purposes.
|
|
29412
29566
|
*
|
|
29413
29567
|
* @access public
|
|
29414
29568
|
* @category Debugging
|
|
@@ -29429,7 +29583,7 @@ function initLogging() {
|
|
|
29429
29583
|
log.addEventListener('log', writeLog);
|
|
29430
29584
|
/**
|
|
29431
29585
|
* Stores console logging status, set with `pendo.enableLogging()` or `pendo.disableLogging()`.
|
|
29432
|
-
* Logs will appear with `[
|
|
29586
|
+
* Logs will appear with `[Pendo Web SDK]` prefixed in the browser console.
|
|
29433
29587
|
*
|
|
29434
29588
|
* @name _pendo_log-enabled
|
|
29435
29589
|
* @category Cookies/localStorage
|
|
@@ -29467,13 +29621,13 @@ var shouldWeLog = function (contexts) {
|
|
|
29467
29621
|
return (!!logOverride || !!isDebuggingEnabled());
|
|
29468
29622
|
};
|
|
29469
29623
|
/**
|
|
29470
|
-
* Logs an output to the console as the [
|
|
29624
|
+
* Logs an output to the console as the [Pendo Web SDK].
|
|
29471
29625
|
*
|
|
29472
29626
|
* @access public
|
|
29473
29627
|
* @category Debugging
|
|
29474
29628
|
* @example
|
|
29475
29629
|
* pendo.log('hello world!')
|
|
29476
|
-
* // [
|
|
29630
|
+
* // [Pendo Web SDK] hello world!
|
|
29477
29631
|
*/
|
|
29478
29632
|
var logPublic = function (msg, ...contexts) {
|
|
29479
29633
|
log.info(msg, { contexts });
|
|
@@ -29530,7 +29684,7 @@ var setActiveContexts = function (contexts) {
|
|
|
29530
29684
|
var doConsoleLog = function (msg, prefix) {
|
|
29531
29685
|
if (!canWeLog())
|
|
29532
29686
|
return;
|
|
29533
|
-
prefix = prefix || '[
|
|
29687
|
+
prefix = prefix || '[Pendo Web SDK] ';
|
|
29534
29688
|
if (msg && msg.length) {
|
|
29535
29689
|
var msgStart = msg.length > 1000 ? msg.length - 1000 : 0;
|
|
29536
29690
|
if (msgStart) {
|
|
@@ -29710,8 +29864,8 @@ var validateInstall = function validateInstall(skipLogging) {
|
|
|
29710
29864
|
}
|
|
29711
29865
|
if (!skipLogging)
|
|
29712
29866
|
console.group('Pendo Install Validation');
|
|
29713
|
-
if (!pendo$1.apiKey) {
|
|
29714
|
-
handleLogging('error', 'No Pendo
|
|
29867
|
+
if (!pendo$1.apiKey && !pendo$1.publicAppId) {
|
|
29868
|
+
handleLogging('error', 'No Pendo public app ID configured. Make sure to call pendo.initialize() with a valid Pendo public app ID.', 'publicAppId');
|
|
29715
29869
|
}
|
|
29716
29870
|
var visitorId = get_visitor_id();
|
|
29717
29871
|
if (isAnonymousVisitor(visitorId)) {
|
|
@@ -32684,7 +32838,7 @@ var FramesModule = (function () {
|
|
|
32684
32838
|
agentStorage.registry.addSession(TAB_ID);
|
|
32685
32839
|
/**
|
|
32686
32840
|
* When a browser window is cloned the `pendo_tabId` is copied to the new window.
|
|
32687
|
-
* The Pendo
|
|
32841
|
+
* The Pendo Web SDK detects this, creates a new `pendo_tabId`, and stores the old
|
|
32688
32842
|
* `pendo_tabId` in `pendo_parentTabId`.
|
|
32689
32843
|
*
|
|
32690
32844
|
* @name pendo_parentTabId
|
|
@@ -36145,7 +36299,7 @@ function LauncherBadge(config) {
|
|
|
36145
36299
|
element.src = replaceWithContentHost(config.launcherBadgeUrl);
|
|
36146
36300
|
}
|
|
36147
36301
|
element.onerror = function (e) {
|
|
36148
|
-
log.info('[
|
|
36302
|
+
log.info('[Pendo Web SDK] Error! Unable to load guide center image ' + config.launcherBadgeUrl);
|
|
36149
36303
|
log.critical('ERROR in when attempting to render guide center badge image', { imgSrc: config.launcherBadgeUrl });
|
|
36150
36304
|
};
|
|
36151
36305
|
if (isBrowserInQuirksmode()) {
|
|
@@ -37645,6 +37799,43 @@ const EventProperties = (function () {
|
|
|
37645
37799
|
}
|
|
37646
37800
|
})();
|
|
37647
37801
|
|
|
37802
|
+
/**
|
|
37803
|
+
* OEM Account ID Plugin
|
|
37804
|
+
*
|
|
37805
|
+
* This plugin reads the oemAccountId from configuration and sets it onto every
|
|
37806
|
+
* captured event if the oemAccountId is defined.
|
|
37807
|
+
*/
|
|
37808
|
+
const OemAccountId = (function () {
|
|
37809
|
+
let pluginAPI;
|
|
37810
|
+
let oemAccountId;
|
|
37811
|
+
let eventCapturedHandler;
|
|
37812
|
+
return {
|
|
37813
|
+
name: 'OemAccountId',
|
|
37814
|
+
initialize,
|
|
37815
|
+
teardown
|
|
37816
|
+
};
|
|
37817
|
+
function initialize(_, PluginAPI) {
|
|
37818
|
+
pluginAPI = PluginAPI;
|
|
37819
|
+
oemAccountId = pluginAPI.ConfigReader.get('oemAccountId');
|
|
37820
|
+
if (oemAccountId) {
|
|
37821
|
+
eventCapturedHandler = function (event) {
|
|
37822
|
+
setOemAccountId(event);
|
|
37823
|
+
};
|
|
37824
|
+
pluginAPI.Events.on('eventCaptured', eventCapturedHandler);
|
|
37825
|
+
}
|
|
37826
|
+
}
|
|
37827
|
+
function teardown() {
|
|
37828
|
+
if (eventCapturedHandler) {
|
|
37829
|
+
pluginAPI.Events.off('eventCaptured', eventCapturedHandler);
|
|
37830
|
+
}
|
|
37831
|
+
}
|
|
37832
|
+
function setOemAccountId(event) {
|
|
37833
|
+
if (oemAccountId && event && event.data && event.data[0]) {
|
|
37834
|
+
event.data[0].oem_account_id = oemAccountId;
|
|
37835
|
+
}
|
|
37836
|
+
}
|
|
37837
|
+
})();
|
|
37838
|
+
|
|
37648
37839
|
var debugging;
|
|
37649
37840
|
function debuggerExports() {
|
|
37650
37841
|
return {
|
|
@@ -38390,6 +38581,12 @@ const EmbeddedGuides = (function () {
|
|
|
38390
38581
|
function processEmbeddedGuides() {
|
|
38391
38582
|
_.forEach(embeddedGuides, function (guide) {
|
|
38392
38583
|
guide.process();
|
|
38584
|
+
if (guide.isShownInThisFrame()) {
|
|
38585
|
+
const activeStep = guide.getActiveStep();
|
|
38586
|
+
if (activeStep) {
|
|
38587
|
+
syncColorMode(activeStep, true);
|
|
38588
|
+
}
|
|
38589
|
+
}
|
|
38393
38590
|
});
|
|
38394
38591
|
}
|
|
38395
38592
|
function hideAllEmbeddedGuides() {
|
|
@@ -38674,8 +38871,8 @@ class SegmentFlags {
|
|
|
38674
38871
|
v: this.pendo.VERSION,
|
|
38675
38872
|
ct: (new Date()).getTime()
|
|
38676
38873
|
};
|
|
38677
|
-
if (this.api.agent.treatAsAdoptPartner()
|
|
38678
|
-
queryString.
|
|
38874
|
+
if (this.api.agent.treatAsAdoptPartner()) {
|
|
38875
|
+
this.api.agent.addAccountIdParams(queryString, params.accountId, this.api.ConfigReader.get('oemAccountId'));
|
|
38679
38876
|
}
|
|
38680
38877
|
const endpoint = this.pendo.LOADER === 'script' ? 'segmentflag.js' : 'segmentflag.json';
|
|
38681
38878
|
let url = this.api.transmit.buildBaseDataUrl(endpoint, this.pendo.apiKey, queryString);
|
|
@@ -40051,6 +40248,7 @@ function registerBuiltInPlugins() {
|
|
|
40051
40248
|
registerPlugin(Branding);
|
|
40052
40249
|
registerPlugin(ActionAutomation);
|
|
40053
40250
|
registerPlugin(EventProperties);
|
|
40251
|
+
registerPlugin(OemAccountId);
|
|
40054
40252
|
registerPlugin(StepTimeoutMonitor);
|
|
40055
40253
|
registerPlugin(DebuggerLauncher);
|
|
40056
40254
|
registerPlugin(FrustrationEvent);
|
|
@@ -47707,6 +47905,7 @@ function record(options = {}) {
|
|
|
47707
47905
|
recordDOM = true,
|
|
47708
47906
|
recordCanvas = false,
|
|
47709
47907
|
recordCrossOriginIframes = false,
|
|
47908
|
+
emitFromIframe = false,
|
|
47710
47909
|
recordAfter = options.recordAfter === "DOMContentLoaded" ? options.recordAfter : "load",
|
|
47711
47910
|
userTriggeredOnInput = false,
|
|
47712
47911
|
collectFonts = false,
|
|
@@ -47717,7 +47916,7 @@ function record(options = {}) {
|
|
|
47717
47916
|
errorHandler: errorHandler2
|
|
47718
47917
|
} = options;
|
|
47719
47918
|
registerErrorHandler(errorHandler2);
|
|
47720
|
-
const inEmittingFrame = recordCrossOriginIframes ? window.parent === window : true;
|
|
47919
|
+
const inEmittingFrame = emitFromIframe ? true : recordCrossOriginIframes ? window.parent === window : true;
|
|
47721
47920
|
let passEmitsToParent = false;
|
|
47722
47921
|
if (!inEmittingFrame) {
|
|
47723
47922
|
try {
|
|
@@ -53376,6 +53575,7 @@ const RECORDING_CONFIG_WORKERURL = 'recording.workerUrl';
|
|
|
53376
53575
|
const RECORDING_CONFIG_ON_RECORDING_START = 'recording.onRecordingStart';
|
|
53377
53576
|
const RECORDING_CONFIG_ON_RECORDING_STOP = 'recording.onRecordingStop';
|
|
53378
53577
|
const RECORDING_CONFIG_WORKER_OVERRIDE = 'recording.workerOverride';
|
|
53578
|
+
const RECORDING_CONFIG_TREAT_IFRAME_AS_ROOT = 'recording.treatIframeAsRoot';
|
|
53379
53579
|
const RESOURCE_CACHING = 'resourceCaching';
|
|
53380
53580
|
const ONE_DAY_IN_MILLISECONDS = 24 * 60 * 60 * 1000;
|
|
53381
53581
|
const THIRTY_MINUTES = 1000 * 60 * 30;
|
|
@@ -53470,6 +53670,22 @@ class SessionRecorder {
|
|
|
53470
53670
|
* @type {object}
|
|
53471
53671
|
*/
|
|
53472
53672
|
cf.addOption(RECORDING_CONFIG_WORKER_OVERRIDE, [cf.sources.PENDO_CONFIG_SRC], undefined);
|
|
53673
|
+
/**
|
|
53674
|
+
* Option to treat this iframe as the root recording frame.
|
|
53675
|
+
*
|
|
53676
|
+
* When set to true, this iframe will emit its own recording events and create its own
|
|
53677
|
+
* recording session, acting as a root recording frame.
|
|
53678
|
+
*
|
|
53679
|
+
* When set to false or undefined (default), recording events from this iframe will be passed up
|
|
53680
|
+
* to the parent frame for handling.
|
|
53681
|
+
*
|
|
53682
|
+
* @access public
|
|
53683
|
+
* @category Config/Replay
|
|
53684
|
+
* @name recording.treatIframeAsRoot
|
|
53685
|
+
* @default undefined
|
|
53686
|
+
* @type {boolean}
|
|
53687
|
+
*/
|
|
53688
|
+
cf.addOption(RECORDING_CONFIG_TREAT_IFRAME_AS_ROOT, [cf.sources.SNIPPET_SRC], undefined);
|
|
53473
53689
|
cf.addOption(RESOURCE_CACHING, [cf.sources.PENDO_CONFIG_SRC], undefined);
|
|
53474
53690
|
}
|
|
53475
53691
|
initialize(pendo, PluginAPI) {
|
|
@@ -53692,7 +53908,8 @@ class SessionRecorder {
|
|
|
53692
53908
|
// we need to concat hidden selectors to re-use block selector logic
|
|
53693
53909
|
blockSelector: blockedSelectors.concat(hiddenSelectors).join(','),
|
|
53694
53910
|
hideSelector: hiddenSelectors.join(','),
|
|
53695
|
-
recordCrossOriginIframes: recordingOptions.recordCrossOriginIframes != null ? recordingOptions.recordCrossOriginIframes : true
|
|
53911
|
+
recordCrossOriginIframes: recordingOptions.recordCrossOriginIframes != null ? recordingOptions.recordCrossOriginIframes : true,
|
|
53912
|
+
emitFromIframe: !!this.api.ConfigReader.get(RECORDING_CONFIG_TREAT_IFRAME_AS_ROOT)
|
|
53696
53913
|
};
|
|
53697
53914
|
return config;
|
|
53698
53915
|
}
|
|
@@ -55987,19 +56204,21 @@ var ConfigReader = (function () {
|
|
|
55987
56204
|
function initializeOptions() {
|
|
55988
56205
|
// Core
|
|
55989
56206
|
/**
|
|
55990
|
-
* When included, all analytics events will be sent to each of the
|
|
55991
|
-
* only sent to the primary
|
|
56207
|
+
* Formerly `additionalApiKeys`. When included, all analytics events will be sent to each of the public app IDs in the list (guide events are
|
|
56208
|
+
* only sent to the primary public app ID). This will only function if there are no `additionalPublicAppIds` set on
|
|
55992
56209
|
* the configuration included in the downloaded Agent.
|
|
55993
56210
|
*
|
|
55994
56211
|
* @access public
|
|
55995
56212
|
* @category Config/Core
|
|
55996
|
-
* @name
|
|
56213
|
+
* @name additionalPublicAppIds
|
|
55997
56214
|
* @default []
|
|
55998
56215
|
* @type {string[]}
|
|
55999
56216
|
*/
|
|
56217
|
+
addOption('additionalPublicAppIds', [PENDO_CONFIG_SRC, SNIPPET_SRC]);
|
|
56000
56218
|
addOption('additionalApiKeys', [PENDO_CONFIG_SRC, SNIPPET_SRC]);
|
|
56001
56219
|
addOption('allowedOriginServers');
|
|
56002
56220
|
addOption('allowedOriginServerHashes');
|
|
56221
|
+
addOption('allowMixedApplicationFrames', [SNIPPET_SRC, PENDO_CONFIG_SRC], true);
|
|
56003
56222
|
addOption('allowMixedApiKeyFrames', [SNIPPET_SRC, PENDO_CONFIG_SRC], true);
|
|
56004
56223
|
/**
|
|
56005
56224
|
* A function that returns either an array of strings or an object to decorate the url for events.
|
|
@@ -56013,15 +56232,16 @@ var ConfigReader = (function () {
|
|
|
56013
56232
|
*/
|
|
56014
56233
|
addOption('annotateUrl', [SNIPPET_SRC]);
|
|
56015
56234
|
/**
|
|
56016
|
-
* A primary
|
|
56235
|
+
* Formerly `apiKey`. A primary public app ID to send data to from the Agent. This will only function if there is no `publicAppId` set
|
|
56017
56236
|
* on the configuration included in the downloaded Agent.
|
|
56018
56237
|
*
|
|
56019
56238
|
* @access public
|
|
56020
56239
|
* @category Config/Core
|
|
56021
|
-
* @name
|
|
56240
|
+
* @name publicAppId
|
|
56022
56241
|
* @default undefined
|
|
56023
56242
|
* @type {string}
|
|
56024
56243
|
*/
|
|
56244
|
+
addOption('publicAppId', [PENDO_CONFIG_SRC, SNIPPET_SRC]);
|
|
56025
56245
|
addOption('apiKey', [PENDO_CONFIG_SRC, SNIPPET_SRC]);
|
|
56026
56246
|
addOption('assetHost', [SNIPPET_SRC, PENDO_CONFIG_SRC]);
|
|
56027
56247
|
/**
|
|
@@ -56659,18 +56879,19 @@ var ConfigReader = (function () {
|
|
|
56659
56879
|
*/
|
|
56660
56880
|
addOption('inlineStyleNonce', [SNIPPET_SRC]);
|
|
56661
56881
|
/**
|
|
56662
|
-
* Specify a preferred
|
|
56663
|
-
* guide display. In installations with more than 2
|
|
56664
|
-
* list (e.g. `
|
|
56665
|
-
* or only one frame should specify the
|
|
56882
|
+
* Formerly `leaderKey` Specify a preferred publicAppId to lead the multi-application iframe installation to make decisions about automatic
|
|
56883
|
+
* guide display. In installations with more than 2 publicAppIds, the leaderApplication can be specified as a priority
|
|
56884
|
+
* list (e.g. `leaderApplication: ['key1', 'key2', ...]`). Either all frames must agree on the leaderApplication setting,
|
|
56885
|
+
* or only one frame should specify the leaderApplication. If neither of these conditions are met, the default leader
|
|
56666
56886
|
* determination logic (top frame or earliest to join) will be used.
|
|
56667
56887
|
*
|
|
56668
56888
|
* @access public
|
|
56669
56889
|
* @category Config/Guides
|
|
56670
|
-
* @name
|
|
56890
|
+
* @name leaderApplication
|
|
56671
56891
|
* @default []
|
|
56672
56892
|
* @type {string[]}
|
|
56673
56893
|
*/
|
|
56894
|
+
addOption('leaderApplication', [SNIPPET_SRC, PENDO_CONFIG_SRC], []);
|
|
56674
56895
|
addOption('leaderKey', [SNIPPET_SRC, PENDO_CONFIG_SRC], []);
|
|
56675
56896
|
/**
|
|
56676
56897
|
* If `true`, custom code blocks in building block guides will not be allowed to run. Also, classic guides
|
|
@@ -56731,6 +56952,8 @@ var ConfigReader = (function () {
|
|
|
56731
56952
|
addOption('designerAgentPluginsLoader', [PENDO_CONFIG_SRC, SNIPPET_SRC]);
|
|
56732
56953
|
addOption('guideContentLoader', [PENDO_CONFIG_SRC]);
|
|
56733
56954
|
addOption('trainingPartner');
|
|
56955
|
+
addOption('oemAccountId', [SNIPPET_SRC]);
|
|
56956
|
+
addOption('whiteLabelSettings', [PENDO_CONFIG_SRC]);
|
|
56734
56957
|
// Frustration
|
|
56735
56958
|
addOption('errorClickLogging', [PENDO_CONFIG_SRC], false);
|
|
56736
56959
|
// Embedded Guides
|
|
@@ -56739,6 +56962,7 @@ var ConfigReader = (function () {
|
|
|
56739
56962
|
addOption('formValidation', [PENDO_CONFIG_SRC], false);
|
|
56740
56963
|
// Performance Metrics
|
|
56741
56964
|
addOption('performanceMetricsEnabled', [SNIPPET_SRC, PENDO_CONFIG_SRC], true);
|
|
56965
|
+
addOption('performanceMetricsSampleRate', [SNIPPET_SRC, PENDO_CONFIG_SRC], 0);
|
|
56742
56966
|
}
|
|
56743
56967
|
initializeOptions();
|
|
56744
56968
|
var sourceGetters = {};
|
|
@@ -57534,10 +57758,8 @@ class DevlogTransport {
|
|
|
57534
57758
|
}
|
|
57535
57759
|
buildGetUrl(baseUrl, jzb) {
|
|
57536
57760
|
const params = {};
|
|
57537
|
-
|
|
57538
|
-
|
|
57539
|
-
if (isAdoptPartner && accountId && accountId !== 'ACCOUNT-UNIQUE-ID') {
|
|
57540
|
-
params.acc = this.pluginAPI.util.base64EncodeString(accountId);
|
|
57761
|
+
if (this.pluginAPI.agent.treatAsAdoptPartner()) {
|
|
57762
|
+
this.pluginAPI.agent.addAccountIdParams(params, this.pendo.get_account_id(), this.pluginAPI.ConfigReader.get('oemAccountId'));
|
|
57541
57763
|
}
|
|
57542
57764
|
const jwtOptions = this.pluginAPI.agent.getJwtInfoCopy();
|
|
57543
57765
|
if (!this.pendo._.isEmpty(jwtOptions)) {
|
|
@@ -57583,10 +57805,8 @@ class DevlogTransport {
|
|
|
57583
57805
|
events: jzb,
|
|
57584
57806
|
browser_time: this.pluginAPI.util.getNow()
|
|
57585
57807
|
};
|
|
57586
|
-
|
|
57587
|
-
|
|
57588
|
-
if (isAdoptPartner && accountId && accountId !== 'ACCOUNT-UNIQUE-ID') {
|
|
57589
|
-
bodyPayload.acc = this.pluginAPI.util.base64EncodeString(accountId);
|
|
57808
|
+
if (this.pluginAPI.agent.treatAsAdoptPartner()) {
|
|
57809
|
+
this.pluginAPI.agent.addAccountIdParams(bodyPayload, this.pendo.get_account_id(), this.pluginAPI.ConfigReader.get('oemAccountId'));
|
|
57590
57810
|
}
|
|
57591
57811
|
const body = JSON.stringify(this.pendo._.extend(bodyPayload, jwtOptions));
|
|
57592
57812
|
return this.post(url, {
|