mixpanel-browser 2.77.0 → 2.79.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/.claude/settings.local.json +6 -9
- package/.eslintrc.json +12 -0
- package/.github/workflows/openfeature-provider-tests.yml +31 -0
- package/CHANGELOG.md +11 -0
- package/build.sh +2 -2
- package/dist/async-modules/{mixpanel-recorder-wIWnMDLA.min.js → mixpanel-recorder-D5HJyV2E.min.js} +2 -2
- package/dist/async-modules/mixpanel-recorder-D5HJyV2E.min.js.map +1 -0
- package/dist/async-modules/{mixpanel-recorder-DLKbUIEE.js → mixpanel-recorder-P6SEnnPV.js} +57 -33
- package/dist/async-modules/mixpanel-targeting-1L9FyetZ.min.js +2 -0
- package/dist/async-modules/mixpanel-targeting-1L9FyetZ.min.js.map +1 -0
- package/dist/async-modules/{mixpanel-targeting-CmVvUyFM.js → mixpanel-targeting-BBMVbgJF.js} +24 -13
- package/dist/mixpanel-core.cjs.d.ts +46 -1
- package/dist/mixpanel-core.cjs.js +671 -272
- package/dist/mixpanel-recorder.js +57 -33
- package/dist/mixpanel-recorder.min.js +1 -1
- package/dist/mixpanel-recorder.min.js.map +1 -1
- package/dist/mixpanel-targeting.js +24 -13
- package/dist/mixpanel-targeting.min.js +1 -1
- package/dist/mixpanel-targeting.min.js.map +1 -1
- package/dist/mixpanel-with-async-modules.cjs.d.ts +46 -1
- package/dist/mixpanel-with-async-modules.cjs.js +673 -274
- package/dist/mixpanel-with-async-recorder.cjs.d.ts +46 -1
- package/dist/mixpanel-with-async-recorder.cjs.js +673 -274
- package/dist/mixpanel-with-recorder.d.ts +46 -1
- package/dist/mixpanel-with-recorder.js +596 -197
- package/dist/mixpanel-with-recorder.min.d.ts +46 -1
- package/dist/mixpanel-with-recorder.min.js +1 -1
- package/dist/mixpanel.amd.d.ts +46 -1
- package/dist/mixpanel.amd.js +596 -197
- package/dist/mixpanel.cjs.d.ts +46 -1
- package/dist/mixpanel.cjs.js +596 -197
- package/dist/mixpanel.globals.js +673 -274
- package/dist/mixpanel.min.js +200 -189
- package/dist/mixpanel.module.d.ts +46 -1
- package/dist/mixpanel.module.js +596 -197
- package/dist/mixpanel.umd.d.ts +46 -1
- package/dist/mixpanel.umd.js +596 -197
- package/package.json +1 -1
- package/packages/openfeature-web-provider/README.md +357 -0
- package/packages/openfeature-web-provider/package-lock.json +1636 -0
- package/packages/openfeature-web-provider/package.json +51 -0
- package/packages/openfeature-web-provider/rollup.config.browser.mjs +26 -0
- package/packages/openfeature-web-provider/src/MixpanelProvider.ts +302 -0
- package/packages/openfeature-web-provider/src/index.ts +1 -0
- package/packages/openfeature-web-provider/src/types.ts +72 -0
- package/packages/openfeature-web-provider/test/MixpanelProvider.spec.ts +484 -0
- package/packages/openfeature-web-provider/tsconfig.json +15 -0
- package/src/autocapture/index.js +7 -2
- package/src/config.js +1 -1
- package/src/flags/CLAUDE.md +24 -0
- package/src/flags/flags-persistence.js +176 -0
- package/src/flags/index.js +278 -98
- package/src/index.d.ts +46 -1
- package/src/mixpanel-core.js +27 -8
- package/src/recorder/idb-config.js +16 -0
- package/src/recorder/recording-registry.js +7 -2
- package/src/recorder/session-recording.js +9 -4
- package/src/recorder-manager.js +7 -2
- package/src/request-queue.js +1 -2
- package/src/shared-lock.js +2 -3
- package/src/storage/indexed-db.js +16 -15
- package/src/storage/local-storage.js +5 -3
- package/src/utils.js +25 -12
- package/testServer.js +2 -0
- package/tsconfig.base.json +9 -0
- package/dist/async-modules/mixpanel-recorder-wIWnMDLA.min.js.map +0 -1
- package/dist/async-modules/mixpanel-targeting-CTcftSJC.min.js +0 -2
- package/dist/async-modules/mixpanel-targeting-CTcftSJC.min.js.map +0 -1
package/src/mixpanel-core.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint camelcase: "off" */
|
|
2
2
|
import {Config, TARGETING_FILENAME} from './config';
|
|
3
|
-
import { MAX_RECORDING_MS, _, console, userAgent, document, navigator, slice, NOOP_FUNC, JSONStringify } from './utils';
|
|
3
|
+
import { MAX_RECORDING_MS, _, console, userAgent, document, navigator, slice, NOOP_FUNC, JSONStringify, safewrap } from './utils';
|
|
4
4
|
import { window } from './window';
|
|
5
5
|
import { Autocapture } from './autocapture';
|
|
6
6
|
import { FeatureFlagManager } from './flags';
|
|
@@ -341,6 +341,7 @@ MixpanelLib.prototype._init = function(token, config, name) {
|
|
|
341
341
|
'disable_all_events': false,
|
|
342
342
|
'identify_called': false
|
|
343
343
|
};
|
|
344
|
+
this._remote_settings_strict_disabled = false;
|
|
344
345
|
|
|
345
346
|
// set up request queueing/batching
|
|
346
347
|
this.request_batchers = {};
|
|
@@ -415,9 +416,6 @@ MixpanelLib.prototype._init = function(token, config, name) {
|
|
|
415
416
|
this.flags.init();
|
|
416
417
|
this['flags'] = this.flags;
|
|
417
418
|
|
|
418
|
-
this.autocapture = new Autocapture(this);
|
|
419
|
-
this.autocapture.init();
|
|
420
|
-
|
|
421
419
|
this._init_tab_id();
|
|
422
420
|
|
|
423
421
|
// Based on remote_settings_mode, fetch remote settings and then start session recording if applicable
|
|
@@ -429,6 +427,9 @@ MixpanelLib.prototype._init = function(token, config, name) {
|
|
|
429
427
|
} else {
|
|
430
428
|
this.__session_recording_init_promise = this._check_and_start_session_recording();
|
|
431
429
|
}
|
|
430
|
+
|
|
431
|
+
this.autocapture = new Autocapture(this);
|
|
432
|
+
this.autocapture.init();
|
|
432
433
|
};
|
|
433
434
|
|
|
434
435
|
/**
|
|
@@ -475,9 +476,19 @@ MixpanelLib.prototype._check_and_start_session_recording = addOptOutCheckMixpane
|
|
|
475
476
|
return this.recorderManager.checkAndStartSessionRecording(force_start);
|
|
476
477
|
});
|
|
477
478
|
|
|
478
|
-
MixpanelLib.prototype._start_recording_on_event = function(event_name, properties) {
|
|
479
|
-
|
|
480
|
-
|
|
479
|
+
MixpanelLib.prototype._start_recording_on_event = safewrap(function(event_name, properties) {
|
|
480
|
+
// Wait for recording init to complete before evaluating event triggers.
|
|
481
|
+
// This ensures recording_event_triggers config is fully loaded when remote settings are used.
|
|
482
|
+
if (this.__session_recording_init_promise) {
|
|
483
|
+
this.__session_recording_init_promise.then(_.bind(function() {
|
|
484
|
+
// In strict mode, skip recording if remote settings failed
|
|
485
|
+
if (this._remote_settings_strict_disabled) {
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
return this.recorderManager.startRecordingOnEvent(event_name, properties);
|
|
489
|
+
}, this));
|
|
490
|
+
}
|
|
491
|
+
});
|
|
481
492
|
|
|
482
493
|
MixpanelLib.prototype.start_session_recording = function () {
|
|
483
494
|
return this._check_and_start_session_recording(true);
|
|
@@ -776,6 +787,7 @@ MixpanelLib.prototype._fetch_remote_settings = function(mode) {
|
|
|
776
787
|
var disableRecordingIfStrict = function() {
|
|
777
788
|
if (mode === 'strict') {
|
|
778
789
|
self.set_config({'record_sessions_percent': 0});
|
|
790
|
+
self._remote_settings_strict_disabled = true;
|
|
779
791
|
}
|
|
780
792
|
};
|
|
781
793
|
|
|
@@ -1401,6 +1413,10 @@ MixpanelLib.prototype.track_pageview = addOptOutCheckMixpanelLib(function(proper
|
|
|
1401
1413
|
properties
|
|
1402
1414
|
);
|
|
1403
1415
|
|
|
1416
|
+
if (this.is_recording_heatmap_data()) {
|
|
1417
|
+
event_properties['$captured_for_heatmap'] = true;
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1404
1420
|
return this.track(event_name, event_properties);
|
|
1405
1421
|
});
|
|
1406
1422
|
|
|
@@ -1724,7 +1740,9 @@ MixpanelLib.prototype.identify = function(
|
|
|
1724
1740
|
|
|
1725
1741
|
// check feature flags again if distinct id has changed
|
|
1726
1742
|
if (new_distinct_id !== previous_distinct_id) {
|
|
1727
|
-
this.flags.fetchFlags()
|
|
1743
|
+
this.flags.fetchFlags().catch(function() {
|
|
1744
|
+
console.error('[flags] Error fetching flags during identify');
|
|
1745
|
+
});
|
|
1728
1746
|
}
|
|
1729
1747
|
};
|
|
1730
1748
|
|
|
@@ -1742,6 +1760,7 @@ MixpanelLib.prototype.reset = function() {
|
|
|
1742
1760
|
'$device_id': uuid
|
|
1743
1761
|
}, '');
|
|
1744
1762
|
this._check_and_start_session_recording();
|
|
1763
|
+
this.flags.reset();
|
|
1745
1764
|
};
|
|
1746
1765
|
|
|
1747
1766
|
/**
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
var MIXPANEL_BROWSER_DB_NAME = 'mixpanelBrowserDb';
|
|
2
|
+
var RECORDING_EVENTS_STORE_NAME = 'mixpanelRecordingEvents';
|
|
3
|
+
var RECORDING_REGISTRY_STORE_NAME = 'mixpanelRecordingRegistry';
|
|
4
|
+
|
|
5
|
+
// Keeping these two properties closeby, as adding additional stores to a DB in IndexedDB requires a version increment
|
|
6
|
+
var RECORDER_VERSION_DATA = {
|
|
7
|
+
version: 1,
|
|
8
|
+
storeNames: [RECORDING_EVENTS_STORE_NAME, RECORDING_REGISTRY_STORE_NAME]
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
MIXPANEL_BROWSER_DB_NAME,
|
|
13
|
+
RECORDING_EVENTS_STORE_NAME,
|
|
14
|
+
RECORDING_REGISTRY_STORE_NAME,
|
|
15
|
+
RECORDER_VERSION_DATA
|
|
16
|
+
};
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { Promise } from '../promise-polyfill';
|
|
2
|
-
import { IDBStorageWrapper
|
|
2
|
+
import { IDBStorageWrapper } from '../storage/indexed-db';
|
|
3
|
+
import {
|
|
4
|
+
MIXPANEL_BROWSER_DB_NAME,
|
|
5
|
+
RECORDING_REGISTRY_STORE_NAME,
|
|
6
|
+
RECORDER_VERSION_DATA
|
|
7
|
+
} from './idb-config';
|
|
3
8
|
import { SessionRecording } from './session-recording';
|
|
4
9
|
import { isRecordingExpired } from './utils';
|
|
5
10
|
|
|
@@ -9,7 +14,7 @@ import { isRecordingExpired } from './utils';
|
|
|
9
14
|
*/
|
|
10
15
|
var RecordingRegistry = function (options) {
|
|
11
16
|
/** @type {IDBStorageWrapper} */
|
|
12
|
-
this.idb = new IDBStorageWrapper(RECORDING_REGISTRY_STORE_NAME);
|
|
17
|
+
this.idb = new IDBStorageWrapper(MIXPANEL_BROWSER_DB_NAME, RECORDING_REGISTRY_STORE_NAME, RECORDER_VERSION_DATA);
|
|
13
18
|
this.errorReporter = options.errorReporter;
|
|
14
19
|
this.mixpanelInstance = options.mixpanelInstance;
|
|
15
20
|
this.sharedLockStorage = options.sharedLockStorage;
|
|
@@ -4,8 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
import { window } from '../window';
|
|
6
6
|
import { EventType, getRecordConsolePlugin, IncrementalSource } from './rrweb-entrypoint';
|
|
7
|
-
import { MAX_RECORDING_MS, MAX_VALUE_FOR_MIN_RECORDING_MS, console_with_prefix, NOOP_FUNC, _, localStorageSupported, canUseCompressionStream, navigator, userAgent, windowOpera} from '../utils'; // eslint-disable-line camelcase
|
|
8
|
-
import { IDBStorageWrapper
|
|
7
|
+
import { MAX_RECORDING_MS, MAX_VALUE_FOR_MIN_RECORDING_MS, console_with_prefix, NOOP_FUNC, _, localStorageSupported, getLocalStorage, canUseCompressionStream, navigator, userAgent, windowOpera} from '../utils'; // eslint-disable-line camelcase
|
|
8
|
+
import { IDBStorageWrapper } from '../storage/indexed-db';
|
|
9
|
+
import {
|
|
10
|
+
MIXPANEL_BROWSER_DB_NAME,
|
|
11
|
+
RECORDING_EVENTS_STORE_NAME,
|
|
12
|
+
RECORDER_VERSION_DATA
|
|
13
|
+
} from './idb-config';
|
|
9
14
|
import { addOptOutCheckMixpanelLib } from '../gdpr-utils';
|
|
10
15
|
import { RequestBatcher } from '../request-batcher';
|
|
11
16
|
|
|
@@ -111,11 +116,11 @@ var SessionRecording = function(options) {
|
|
|
111
116
|
|
|
112
117
|
// disable persistence if localStorage is not supported
|
|
113
118
|
// request-queue will automatically disable persistence if indexedDB fails to initialize
|
|
114
|
-
var usePersistence = localStorageSupported(options.sharedLockStorage, true) && !this.getConfig('disable_persistence');
|
|
119
|
+
var usePersistence = localStorageSupported(options.sharedLockStorage || getLocalStorage(), true) && !this.getConfig('disable_persistence');
|
|
115
120
|
|
|
116
121
|
// each replay has its own batcher key to avoid conflicts between rrweb events of different recordings
|
|
117
122
|
this.batcherKey = '__mprec_' + this.getConfig('name') + '_' + this.getConfig('token') + '_' + this.replayId;
|
|
118
|
-
this.queueStorage = new IDBStorageWrapper(RECORDING_EVENTS_STORE_NAME);
|
|
123
|
+
this.queueStorage = new IDBStorageWrapper(MIXPANEL_BROWSER_DB_NAME, RECORDING_EVENTS_STORE_NAME, RECORDER_VERSION_DATA);
|
|
119
124
|
this.batcher = new RequestBatcher(this.batcherKey, {
|
|
120
125
|
errorReporter: this.reportError.bind(this),
|
|
121
126
|
flushOnlyOnInterval: true,
|
package/src/recorder-manager.js
CHANGED
|
@@ -4,7 +4,12 @@ import {RECORDER_FILENAME, TARGETING_FILENAME, RECORDER_GLOBAL_NAME} from './con
|
|
|
4
4
|
import { _, console, console_with_prefix, safewrap, safewrapClass } from './utils';
|
|
5
5
|
import { window } from './window';
|
|
6
6
|
import { Promise } from './promise-polyfill';
|
|
7
|
-
import { IDBStorageWrapper
|
|
7
|
+
import { IDBStorageWrapper } from './storage/indexed-db';
|
|
8
|
+
import {
|
|
9
|
+
MIXPANEL_BROWSER_DB_NAME,
|
|
10
|
+
RECORDING_REGISTRY_STORE_NAME,
|
|
11
|
+
RECORDER_VERSION_DATA
|
|
12
|
+
} from './recorder/idb-config';
|
|
8
13
|
import { isRecordingExpired, validateAllowedOrigins } from './recorder/utils';
|
|
9
14
|
import { getTargetingPromise } from './targeting/loader';
|
|
10
15
|
|
|
@@ -43,7 +48,7 @@ RecorderManager.prototype.shouldLoadRecorder = function() {
|
|
|
43
48
|
return Promise.resolve(false);
|
|
44
49
|
}
|
|
45
50
|
|
|
46
|
-
var recording_registry_idb = new IDBStorageWrapper(RECORDING_REGISTRY_STORE_NAME);
|
|
51
|
+
var recording_registry_idb = new IDBStorageWrapper(MIXPANEL_BROWSER_DB_NAME, RECORDING_REGISTRY_STORE_NAME, RECORDER_VERSION_DATA);
|
|
47
52
|
var tab_id = this.getTabId();
|
|
48
53
|
return recording_registry_idb.init()
|
|
49
54
|
.then(function () {
|
package/src/request-queue.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SharedLock } from './shared-lock';
|
|
2
2
|
import { batchedThrottle, cheap_guid, console_with_prefix, localStorageSupported, _ } from './utils'; // eslint-disable-line camelcase
|
|
3
|
-
import { window } from './window';
|
|
4
3
|
import { LocalStorageWrapper } from './storage/local-storage';
|
|
5
4
|
import { Promise } from './promise-polyfill';
|
|
6
5
|
|
|
@@ -29,7 +28,7 @@ var RequestQueue = function (storageKey, options) {
|
|
|
29
28
|
if (this.usePersistence) {
|
|
30
29
|
this.queueStorage = options.queueStorage || new LocalStorageWrapper();
|
|
31
30
|
this.lock = new SharedLock(storageKey, {
|
|
32
|
-
storage: options.sharedLockStorage
|
|
31
|
+
storage: options.sharedLockStorage,
|
|
33
32
|
timeoutMS: options.sharedLockTimeoutMS,
|
|
34
33
|
});
|
|
35
34
|
}
|
package/src/shared-lock.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Promise } from './promise-polyfill';
|
|
2
|
-
import { console_with_prefix, localStorageSupported, _ } from './utils'; // eslint-disable-line camelcase
|
|
3
|
-
import { window } from './window';
|
|
2
|
+
import { console_with_prefix, localStorageSupported, getLocalStorage, _ } from './utils'; // eslint-disable-line camelcase
|
|
4
3
|
|
|
5
4
|
var logger = console_with_prefix('lock');
|
|
6
5
|
|
|
@@ -28,7 +27,7 @@ var SharedLock = function(key, options) {
|
|
|
28
27
|
options = options || {};
|
|
29
28
|
|
|
30
29
|
this.storageKey = key;
|
|
31
|
-
this.storage = options.storage ||
|
|
30
|
+
this.storage = options.storage || getLocalStorage();
|
|
32
31
|
this.pollIntervalMS = options.pollIntervalMS || 100;
|
|
33
32
|
this.timeoutMS = options.timeoutMS || 2000;
|
|
34
33
|
|
|
@@ -1,29 +1,26 @@
|
|
|
1
1
|
import { Promise } from '../promise-polyfill';
|
|
2
2
|
import { window } from '../window';
|
|
3
3
|
|
|
4
|
-
var MIXPANEL_DB_NAME = 'mixpanelBrowserDb';
|
|
5
|
-
|
|
6
|
-
var RECORDING_EVENTS_STORE_NAME = 'mixpanelRecordingEvents';
|
|
7
|
-
var RECORDING_REGISTRY_STORE_NAME = 'mixpanelRecordingRegistry';
|
|
8
|
-
|
|
9
|
-
// note: increment the version number when adding new object stores
|
|
10
|
-
var DB_VERSION = 1;
|
|
11
|
-
var OBJECT_STORES = [RECORDING_EVENTS_STORE_NAME, RECORDING_REGISTRY_STORE_NAME];
|
|
12
|
-
|
|
13
4
|
/**
|
|
14
5
|
* @type {import('./wrapper').StorageWrapper}
|
|
15
6
|
*/
|
|
16
|
-
var IDBStorageWrapper = function (storeName) {
|
|
7
|
+
var IDBStorageWrapper = function (dbName, storeName, versionData) {
|
|
8
|
+
this.dbName = dbName;
|
|
9
|
+
this.storeName = storeName;
|
|
10
|
+
this.version = versionData.version;
|
|
11
|
+
this.storeNamesInDb = versionData.storeNames;
|
|
17
12
|
/**
|
|
18
13
|
* @type {Promise<IDBDatabase>|null}
|
|
19
14
|
*/
|
|
20
15
|
this.dbPromise = null;
|
|
21
|
-
this.storeName = storeName;
|
|
22
16
|
};
|
|
23
17
|
|
|
24
18
|
IDBStorageWrapper.prototype._openDb = function () {
|
|
19
|
+
var dbName = this.dbName;
|
|
20
|
+
var version = this.version;
|
|
21
|
+
var storeNamesInDb = this.storeNamesInDb;
|
|
25
22
|
return new Promise(function (resolve, reject) {
|
|
26
|
-
var openRequest = window.indexedDB.open(
|
|
23
|
+
var openRequest = window.indexedDB.open(dbName, version);
|
|
27
24
|
openRequest['onerror'] = function () {
|
|
28
25
|
reject(openRequest.error);
|
|
29
26
|
};
|
|
@@ -35,8 +32,10 @@ IDBStorageWrapper.prototype._openDb = function () {
|
|
|
35
32
|
openRequest['onupgradeneeded'] = function (ev) {
|
|
36
33
|
var db = ev.target.result;
|
|
37
34
|
|
|
38
|
-
|
|
39
|
-
db.
|
|
35
|
+
storeNamesInDb.forEach(function (storeName) {
|
|
36
|
+
if (!db.objectStoreNames.contains(storeName)) {
|
|
37
|
+
db.createObjectStore(storeName);
|
|
38
|
+
}
|
|
40
39
|
});
|
|
41
40
|
};
|
|
42
41
|
});
|
|
@@ -128,4 +127,6 @@ IDBStorageWrapper.prototype.getAll = function () {
|
|
|
128
127
|
});
|
|
129
128
|
};
|
|
130
129
|
|
|
131
|
-
export {
|
|
130
|
+
export {
|
|
131
|
+
IDBStorageWrapper
|
|
132
|
+
};
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { Promise } from '../promise-polyfill';
|
|
2
|
-
import { _, JSONParse, JSONStringify } from '../utils'; // eslint-disable-line camelcase
|
|
3
|
-
import { window } from '../window';
|
|
2
|
+
import { _, JSONParse, JSONStringify, getLocalStorage } from '../utils'; // eslint-disable-line camelcase
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* @type {import('./wrapper').StorageWrapper}
|
|
7
6
|
*/
|
|
8
7
|
var LocalStorageWrapper = function (storageOverride) {
|
|
9
|
-
this.storage = storageOverride ||
|
|
8
|
+
this.storage = storageOverride || getLocalStorage();
|
|
10
9
|
};
|
|
11
10
|
|
|
12
11
|
LocalStorageWrapper.prototype.init = function () {
|
|
12
|
+
if (!this.storage) {
|
|
13
|
+
return Promise.reject(new Error('localStorage is not available'));
|
|
14
|
+
}
|
|
13
15
|
return Promise.resolve();
|
|
14
16
|
};
|
|
15
17
|
|
package/src/utils.js
CHANGED
|
@@ -104,6 +104,7 @@ var log_func_with_prefix = function(func, prefix) {
|
|
|
104
104
|
var console_with_prefix = function(prefix) {
|
|
105
105
|
return {
|
|
106
106
|
log: log_func_with_prefix(console.log, prefix),
|
|
107
|
+
warn: log_func_with_prefix(console.warn, prefix),
|
|
107
108
|
error: log_func_with_prefix(console.error, prefix),
|
|
108
109
|
critical: log_func_with_prefix(console.critical, prefix)
|
|
109
110
|
};
|
|
@@ -1050,7 +1051,8 @@ var localStorageSupported = function(storage, forceCheck) {
|
|
|
1050
1051
|
if (_localStorageSupported !== null && !forceCheck) {
|
|
1051
1052
|
return _localStorageSupported;
|
|
1052
1053
|
}
|
|
1053
|
-
|
|
1054
|
+
|
|
1055
|
+
return _localStorageSupported = _testStorageSupported(storage);
|
|
1054
1056
|
};
|
|
1055
1057
|
|
|
1056
1058
|
var _sessionStorageSupported = null;
|
|
@@ -1058,7 +1060,8 @@ var sessionStorageSupported = function(storage, forceCheck) {
|
|
|
1058
1060
|
if (_sessionStorageSupported !== null && !forceCheck) {
|
|
1059
1061
|
return _sessionStorageSupported;
|
|
1060
1062
|
}
|
|
1061
|
-
|
|
1063
|
+
|
|
1064
|
+
return _sessionStorageSupported = _testStorageSupported(storage);
|
|
1062
1065
|
};
|
|
1063
1066
|
|
|
1064
1067
|
function _storageWrapper(storage, name, is_supported_fn) {
|
|
@@ -1108,17 +1111,26 @@ function _storageWrapper(storage, name, is_supported_fn) {
|
|
|
1108
1111
|
};
|
|
1109
1112
|
}
|
|
1110
1113
|
|
|
1111
|
-
// Safari
|
|
1112
|
-
//
|
|
1113
|
-
var
|
|
1114
|
-
try {
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
}
|
|
1114
|
+
// Safari and other browsers may error out accessing localStorage/sessionStorage
|
|
1115
|
+
// when cookies are disabled, so wrap access in a try-catch.
|
|
1116
|
+
var getLocalStorage = function() {
|
|
1117
|
+
try {
|
|
1118
|
+
return window.localStorage; // eslint-disable-line no-restricted-properties
|
|
1119
|
+
} catch (_err) {
|
|
1120
|
+
return null;
|
|
1121
|
+
}
|
|
1122
|
+
};
|
|
1123
|
+
|
|
1124
|
+
var getSessionStorage = function() {
|
|
1125
|
+
try {
|
|
1126
|
+
return window.sessionStorage; // eslint-disable-line no-restricted-properties
|
|
1127
|
+
} catch (_err) {
|
|
1128
|
+
return null;
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1119
1131
|
|
|
1120
|
-
_.localStorage = _storageWrapper(
|
|
1121
|
-
_.sessionStorage = _storageWrapper(
|
|
1132
|
+
_.localStorage = _storageWrapper(getLocalStorage(), 'localStorage', localStorageSupported);
|
|
1133
|
+
_.sessionStorage = _storageWrapper(getSessionStorage(), 'sessionStorage', sessionStorageSupported);
|
|
1122
1134
|
|
|
1123
1135
|
_.register_event = (function() {
|
|
1124
1136
|
// written by Dean Edwards, 2005
|
|
@@ -1810,5 +1822,6 @@ export {
|
|
|
1810
1822
|
slice,
|
|
1811
1823
|
urlMatchesRegexList,
|
|
1812
1824
|
userAgent,
|
|
1825
|
+
getLocalStorage,
|
|
1813
1826
|
windowOpera,
|
|
1814
1827
|
};
|
package/testServer.js
CHANGED
|
@@ -124,6 +124,8 @@ for (const [suiteId, suite] of Object.entries(TEST_SUITES)) {
|
|
|
124
124
|
// Cross-origin child iframe page for session recording tests
|
|
125
125
|
app.get('/tests/new/' + suiteId + '-cross-origin-page', function(req, res) {
|
|
126
126
|
res.render('cross-origin-page.pug', {
|
|
127
|
+
customLibUrl: suite.customLibUrl || './static/build/mixpanel.js',
|
|
128
|
+
snippetUrl: suite.snippetUrl || './static/src/loaders/mixpanel-jslib-snippet.js',
|
|
127
129
|
testUrl: './static/build/test/browser/cross-origin-page.js'
|
|
128
130
|
});
|
|
129
131
|
});
|