@myinterview/widget-react 1.1.23-development-94da5c1 → 1.1.23-development-ff49dbb

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/cjs/index.js CHANGED
@@ -5820,7 +5820,7 @@ function getEventForEnvelopeItem(item, type) {
5820
5820
  return Array.isArray(item) ? (item )[1] : undefined;
5821
5821
  }
5822
5822
 
5823
- const SDK_VERSION = '7.51.2';
5823
+ const SDK_VERSION = '7.52.1';
5824
5824
 
5825
5825
  let originalFunctionToString;
5826
5826
 
@@ -6001,8 +6001,9 @@ function _getPossibleEventMessages(event) {
6001
6001
  return [event.message];
6002
6002
  }
6003
6003
  if (event.exception) {
6004
+ const { values } = event.exception;
6004
6005
  try {
6005
- const { type = '', value = '' } = (event.exception.values && event.exception.values[0]) || {};
6006
+ const { type = '', value = '' } = (values && values[values.length - 1]) || {};
6006
6007
  return [`${value}`, `${type}: ${value}`];
6007
6008
  } catch (oO) {
6008
6009
  (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.error(`Cannot extract message for event ${getEventDescription(event)}`);
@@ -11548,6 +11549,475 @@ record.takeFullSnapshot = (isCheckout) => {
11548
11549
  };
11549
11550
  record.mirror = mirror;
11550
11551
 
11552
+ /**
11553
+ * Create a breadcrumb for a replay.
11554
+ */
11555
+ function createBreadcrumb(
11556
+ breadcrumb,
11557
+ ) {
11558
+ return {
11559
+ timestamp: Date.now() / 1000,
11560
+ type: 'default',
11561
+ ...breadcrumb,
11562
+ };
11563
+ }
11564
+
11565
+ var NodeType;
11566
+ (function (NodeType) {
11567
+ NodeType[NodeType["Document"] = 0] = "Document";
11568
+ NodeType[NodeType["DocumentType"] = 1] = "DocumentType";
11569
+ NodeType[NodeType["Element"] = 2] = "Element";
11570
+ NodeType[NodeType["Text"] = 3] = "Text";
11571
+ NodeType[NodeType["CDATA"] = 4] = "CDATA";
11572
+ NodeType[NodeType["Comment"] = 5] = "Comment";
11573
+ })(NodeType || (NodeType = {}));
11574
+
11575
+ /**
11576
+ * Converts a timestamp to ms, if it was in s, or keeps it as ms.
11577
+ */
11578
+ function timestampToMs(timestamp) {
11579
+ const isMs = timestamp > 9999999999;
11580
+ return isMs ? timestamp : timestamp * 1000;
11581
+ }
11582
+
11583
+ /**
11584
+ * Add an event to the event buffer.
11585
+ * `isCheckout` is true if this is either the very first event, or an event triggered by `checkoutEveryNms`.
11586
+ */
11587
+ async function addEvent(
11588
+ replay,
11589
+ event,
11590
+ isCheckout,
11591
+ ) {
11592
+ if (!replay.eventBuffer) {
11593
+ // This implies that `_isEnabled` is false
11594
+ return null;
11595
+ }
11596
+
11597
+ if (replay.isPaused()) {
11598
+ // Do not add to event buffer when recording is paused
11599
+ return null;
11600
+ }
11601
+
11602
+ const timestampInMs = timestampToMs(event.timestamp);
11603
+
11604
+ // Throw out events that happen more than 5 minutes ago. This can happen if
11605
+ // page has been left open and idle for a long period of time and user
11606
+ // comes back to trigger a new session. The performance entries rely on
11607
+ // `performance.timeOrigin`, which is when the page first opened.
11608
+ if (timestampInMs + replay.timeouts.sessionIdlePause < Date.now()) {
11609
+ return null;
11610
+ }
11611
+
11612
+ try {
11613
+ if (isCheckout) {
11614
+ replay.eventBuffer.clear();
11615
+ }
11616
+
11617
+ return await replay.eventBuffer.addEvent(event);
11618
+ } catch (error) {
11619
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.error(error);
11620
+ await replay.stop('addEvent');
11621
+
11622
+ const client = getCurrentHub().getClient();
11623
+
11624
+ if (client) {
11625
+ client.recordDroppedEvent('internal_sdk_error', 'replay');
11626
+ }
11627
+ }
11628
+ }
11629
+
11630
+ /**
11631
+ * Add a breadcrumb event to replay.
11632
+ */
11633
+ function addBreadcrumbEvent(replay, breadcrumb) {
11634
+ if (breadcrumb.category === 'sentry.transaction') {
11635
+ return;
11636
+ }
11637
+
11638
+ if (['ui.click', 'ui.input'].includes(breadcrumb.category )) {
11639
+ replay.triggerUserActivity();
11640
+ } else {
11641
+ replay.checkAndHandleExpiredSession();
11642
+ }
11643
+
11644
+ replay.addUpdate(() => {
11645
+ void addEvent(replay, {
11646
+ type: EventType$1.Custom,
11647
+ // TODO: We were converting from ms to seconds for breadcrumbs, spans,
11648
+ // but maybe we should just keep them as milliseconds
11649
+ timestamp: (breadcrumb.timestamp || 0) * 1000,
11650
+ data: {
11651
+ tag: 'breadcrumb',
11652
+ // normalize to max. 10 depth and 1_000 properties per object
11653
+ payload: normalize(breadcrumb, 10, 1000),
11654
+ },
11655
+ });
11656
+
11657
+ // Do not flush after console log messages
11658
+ return breadcrumb.category === 'console';
11659
+ });
11660
+ }
11661
+
11662
+ /**
11663
+ * Detect a slow click on a button/a tag,
11664
+ * and potentially create a corresponding breadcrumb.
11665
+ */
11666
+ function detectSlowClick(
11667
+ replay,
11668
+ config,
11669
+ clickBreadcrumb,
11670
+ node,
11671
+ ) {
11672
+ if (ignoreElement(node, config)) {
11673
+ return;
11674
+ }
11675
+
11676
+ /*
11677
+ We consider a slow click a click on a button/a, which does not trigger one of:
11678
+ - DOM mutation
11679
+ - Scroll (within 100ms)
11680
+ Within the given threshold time.
11681
+ After time timeout time, we stop listening and mark it as a slow click anyhow.
11682
+ */
11683
+
11684
+ let cleanup = () => {
11685
+ // replaced further down
11686
+ };
11687
+
11688
+ // After timeout time, def. consider this a slow click, and stop watching for mutations
11689
+ const timeout = setTimeout(() => {
11690
+ handleSlowClick(replay, clickBreadcrumb, config.timeout, 'timeout');
11691
+ cleanup();
11692
+ }, config.timeout);
11693
+
11694
+ const mutationHandler = () => {
11695
+ maybeHandleSlowClick(replay, clickBreadcrumb, config.threshold, config.timeout, 'mutation');
11696
+ cleanup();
11697
+ };
11698
+
11699
+ const scrollHandler = () => {
11700
+ maybeHandleSlowClick(replay, clickBreadcrumb, config.scrollTimeout, config.timeout, 'scroll');
11701
+ cleanup();
11702
+ };
11703
+
11704
+ const obs = new MutationObserver(mutationHandler);
11705
+
11706
+ obs.observe(WINDOW.document.documentElement, {
11707
+ attributes: true,
11708
+ characterData: true,
11709
+ childList: true,
11710
+ subtree: true,
11711
+ });
11712
+
11713
+ WINDOW.addEventListener('scroll', scrollHandler);
11714
+
11715
+ // Stop listening to scroll timeouts early
11716
+ const scrollTimeout = setTimeout(() => {
11717
+ WINDOW.removeEventListener('scroll', scrollHandler);
11718
+ }, config.scrollTimeout);
11719
+
11720
+ cleanup = () => {
11721
+ clearTimeout(timeout);
11722
+ clearTimeout(scrollTimeout);
11723
+ obs.disconnect();
11724
+ WINDOW.removeEventListener('scroll', scrollHandler);
11725
+ };
11726
+ }
11727
+
11728
+ function maybeHandleSlowClick(
11729
+ replay,
11730
+ clickBreadcrumb,
11731
+ threshold,
11732
+ timeout,
11733
+ endReason,
11734
+ ) {
11735
+ const now = Date.now();
11736
+ const timeAfterClickMs = now - clickBreadcrumb.timestamp * 1000;
11737
+
11738
+ if (timeAfterClickMs > threshold) {
11739
+ handleSlowClick(replay, clickBreadcrumb, Math.min(timeAfterClickMs, timeout), endReason);
11740
+ return true;
11741
+ }
11742
+
11743
+ return false;
11744
+ }
11745
+
11746
+ function handleSlowClick(
11747
+ replay,
11748
+ clickBreadcrumb,
11749
+ timeAfterClickMs,
11750
+ endReason,
11751
+ ) {
11752
+ const breadcrumb = {
11753
+ message: clickBreadcrumb.message,
11754
+ timestamp: clickBreadcrumb.timestamp,
11755
+ category: 'ui.slowClickDetected',
11756
+ data: {
11757
+ ...clickBreadcrumb.data,
11758
+ url: WINDOW.location.href,
11759
+ // TODO FN: add parametrized route, when possible
11760
+ timeAfterClickMs,
11761
+ endReason,
11762
+ },
11763
+ };
11764
+
11765
+ addBreadcrumbEvent(replay, breadcrumb);
11766
+ }
11767
+
11768
+ const SLOW_CLICK_IGNORE_TAGS = ['SELECT', 'OPTION'];
11769
+
11770
+ function ignoreElement(node, config) {
11771
+ // If <input> tag, we only want to consider input[type='submit'] & input[type='button']
11772
+ if (node.tagName === 'INPUT' && !['submit', 'button'].includes(node.getAttribute('type') || '')) {
11773
+ return true;
11774
+ }
11775
+
11776
+ if (SLOW_CLICK_IGNORE_TAGS.includes(node.tagName)) {
11777
+ return true;
11778
+ }
11779
+
11780
+ // If <a> tag, detect special variants that may not lead to an action
11781
+ // If target !== _self, we may open the link somewhere else, which would lead to no action
11782
+ // Also, when downloading a file, we may not leave the page, but still not trigger an action
11783
+ if (
11784
+ node.tagName === 'A' &&
11785
+ (node.hasAttribute('download') || (node.hasAttribute('target') && node.getAttribute('target') !== '_self'))
11786
+ ) {
11787
+ return true;
11788
+ }
11789
+
11790
+ if (config.ignoreSelector && node.matches(config.ignoreSelector)) {
11791
+ return true;
11792
+ }
11793
+
11794
+ return false;
11795
+ }
11796
+
11797
+ // Note that these are the serialized attributes and not attributes directly on
11798
+ // the DOM Node. Attributes we are interested in:
11799
+ const ATTRIBUTES_TO_RECORD = new Set([
11800
+ 'id',
11801
+ 'class',
11802
+ 'aria-label',
11803
+ 'role',
11804
+ 'name',
11805
+ 'alt',
11806
+ 'title',
11807
+ 'data-test-id',
11808
+ 'data-testid',
11809
+ ]);
11810
+
11811
+ /**
11812
+ * Inclusion list of attributes that we want to record from the DOM element
11813
+ */
11814
+ function getAttributesToRecord(attributes) {
11815
+ const obj = {};
11816
+ for (const key in attributes) {
11817
+ if (ATTRIBUTES_TO_RECORD.has(key)) {
11818
+ let normalizedKey = key;
11819
+
11820
+ if (key === 'data-testid' || key === 'data-test-id') {
11821
+ normalizedKey = 'testId';
11822
+ }
11823
+
11824
+ obj[normalizedKey] = attributes[key];
11825
+ }
11826
+ }
11827
+
11828
+ return obj;
11829
+ }
11830
+
11831
+ const handleDomListener = (
11832
+ replay,
11833
+ ) => {
11834
+ const slowClickExperiment = replay.getOptions()._experiments.slowClicks;
11835
+
11836
+ const slowClickConfig = slowClickExperiment
11837
+ ? {
11838
+ threshold: slowClickExperiment.threshold,
11839
+ timeout: slowClickExperiment.timeout,
11840
+ scrollTimeout: slowClickExperiment.scrollTimeout,
11841
+ ignoreSelector: slowClickExperiment.ignoreSelectors ? slowClickExperiment.ignoreSelectors.join(',') : '',
11842
+ }
11843
+ : undefined;
11844
+
11845
+ return (handlerData) => {
11846
+ if (!replay.isEnabled()) {
11847
+ return;
11848
+ }
11849
+
11850
+ const result = handleDom(handlerData);
11851
+
11852
+ if (!result) {
11853
+ return;
11854
+ }
11855
+
11856
+ const isClick = handlerData.name === 'click';
11857
+ const event = isClick && (handlerData.event );
11858
+ // Ignore clicks if ctrl/alt/meta keys are held down as they alter behavior of clicks (e.g. open in new tab)
11859
+ if (isClick && slowClickConfig && event && !event.altKey && !event.metaKey && !event.ctrlKey) {
11860
+ detectSlowClick(
11861
+ replay,
11862
+ slowClickConfig,
11863
+ result ,
11864
+ getClickTargetNode(handlerData.event) ,
11865
+ );
11866
+ }
11867
+
11868
+ addBreadcrumbEvent(replay, result);
11869
+ };
11870
+ };
11871
+
11872
+ /** Get the base DOM breadcrumb. */
11873
+ function getBaseDomBreadcrumb(target, message) {
11874
+ // `__sn` property is the serialized node created by rrweb
11875
+ const serializedNode = target && isRrwebNode(target) && target.__sn.type === NodeType.Element ? target.__sn : null;
11876
+
11877
+ return {
11878
+ message,
11879
+ data: serializedNode
11880
+ ? {
11881
+ nodeId: serializedNode.id,
11882
+ node: {
11883
+ id: serializedNode.id,
11884
+ tagName: serializedNode.tagName,
11885
+ textContent: target
11886
+ ? Array.from(target.childNodes)
11887
+ .map(
11888
+ (node) => '__sn' in node && node.__sn.type === NodeType.Text && node.__sn.textContent,
11889
+ )
11890
+ .filter(Boolean) // filter out empty values
11891
+ .map(text => (text ).trim())
11892
+ .join('')
11893
+ : '',
11894
+ attributes: getAttributesToRecord(serializedNode.attributes),
11895
+ },
11896
+ }
11897
+ : {},
11898
+ };
11899
+ }
11900
+
11901
+ /**
11902
+ * An event handler to react to DOM events.
11903
+ * Exported for tests.
11904
+ */
11905
+ function handleDom(handlerData) {
11906
+ const { target, message } = getDomTarget(handlerData);
11907
+
11908
+ return createBreadcrumb({
11909
+ category: `ui.${handlerData.name}`,
11910
+ ...getBaseDomBreadcrumb(target, message),
11911
+ });
11912
+ }
11913
+
11914
+ function getDomTarget(handlerData) {
11915
+ const isClick = handlerData.name === 'click';
11916
+
11917
+ let message;
11918
+ let target = null;
11919
+
11920
+ // Accessing event.target can throw (see getsentry/raven-js#838, #768)
11921
+ try {
11922
+ target = isClick ? getClickTargetNode(handlerData.event) : getTargetNode(handlerData.event);
11923
+ message = htmlTreeAsString(target, { maxStringLength: 200 }) || '<unknown>';
11924
+ } catch (e) {
11925
+ message = '<unknown>';
11926
+ }
11927
+
11928
+ return { target, message };
11929
+ }
11930
+
11931
+ function isRrwebNode(node) {
11932
+ return '__sn' in node;
11933
+ }
11934
+
11935
+ function getTargetNode(event) {
11936
+ if (isEventWithTarget(event)) {
11937
+ return event.target ;
11938
+ }
11939
+
11940
+ return event;
11941
+ }
11942
+
11943
+ const INTERACTIVE_SELECTOR = 'button,a';
11944
+
11945
+ // For clicks, we check if the target is inside of a button or link
11946
+ // If so, we use this as the target instead
11947
+ // This is useful because if you click on the image in <button><img></button>,
11948
+ // The target will be the image, not the button, which we don't want here
11949
+ function getClickTargetNode(event) {
11950
+ const target = getTargetNode(event);
11951
+
11952
+ if (!target || !(target instanceof Element)) {
11953
+ return target;
11954
+ }
11955
+
11956
+ const closestInteractive = target.closest(INTERACTIVE_SELECTOR);
11957
+ return closestInteractive || target;
11958
+ }
11959
+
11960
+ function isEventWithTarget(event) {
11961
+ return typeof event === 'object' && !!event && 'target' in event;
11962
+ }
11963
+
11964
+ /** Handle keyboard events & create breadcrumbs. */
11965
+ function handleKeyboardEvent(replay, event) {
11966
+ if (!replay.isEnabled()) {
11967
+ return;
11968
+ }
11969
+
11970
+ replay.triggerUserActivity();
11971
+
11972
+ const breadcrumb = getKeyboardBreadcrumb(event);
11973
+
11974
+ if (!breadcrumb) {
11975
+ return;
11976
+ }
11977
+
11978
+ addBreadcrumbEvent(replay, breadcrumb);
11979
+ }
11980
+
11981
+ /** exported only for tests */
11982
+ function getKeyboardBreadcrumb(event) {
11983
+ const { metaKey, shiftKey, ctrlKey, altKey, key, target } = event;
11984
+
11985
+ // never capture for input fields
11986
+ if (!target || isInputElement(target )) {
11987
+ return null;
11988
+ }
11989
+
11990
+ // Note: We do not consider shift here, as that means "uppercase"
11991
+ const hasModifierKey = metaKey || ctrlKey || altKey;
11992
+ const isCharacterKey = key.length === 1; // other keys like Escape, Tab, etc have a longer length
11993
+
11994
+ // Do not capture breadcrumb if only a word key is pressed
11995
+ // This could leak e.g. user input
11996
+ if (!hasModifierKey && isCharacterKey) {
11997
+ return null;
11998
+ }
11999
+
12000
+ const message = htmlTreeAsString(target, { maxStringLength: 200 }) || '<unknown>';
12001
+ const baseBreadcrumb = getBaseDomBreadcrumb(target , message);
12002
+
12003
+ return createBreadcrumb({
12004
+ category: 'ui.keyDown',
12005
+ message,
12006
+ data: {
12007
+ ...baseBreadcrumb.data,
12008
+ metaKey,
12009
+ shiftKey,
12010
+ ctrlKey,
12011
+ altKey,
12012
+ key,
12013
+ },
12014
+ });
12015
+ }
12016
+
12017
+ function isInputElement(target) {
12018
+ return target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable;
12019
+ }
12020
+
11551
12021
  const NAVIGATION_ENTRY_KEYS = [
11552
12022
  'name',
11553
12023
  'type',
@@ -11685,14 +12155,6 @@ function t(t){let e=t.length;for(;--e>=0;)t[e]=0}const e=new Uint8Array([0,0,0,0
11685
12155
 
11686
12156
  function e(){const e=new Blob([r]);return URL.createObjectURL(e)}
11687
12157
 
11688
- /**
11689
- * Converts a timestamp to ms, if it was in s, or keeps it as ms.
11690
- */
11691
- function timestampToMs(timestamp) {
11692
- const isMs = timestamp > 9999999999;
11693
- return isMs ? timestamp : timestamp * 1000;
11694
- }
11695
-
11696
12158
  /**
11697
12159
  * A basic event buffer that does not do any compression.
11698
12160
  * Used as fallback if the compression worker cannot be loaded or is disabled.
@@ -12270,53 +12732,6 @@ function getSession({
12270
12732
  return { type: 'new', session: newSession };
12271
12733
  }
12272
12734
 
12273
- /**
12274
- * Add an event to the event buffer.
12275
- * `isCheckout` is true if this is either the very first event, or an event triggered by `checkoutEveryNms`.
12276
- */
12277
- async function addEvent(
12278
- replay,
12279
- event,
12280
- isCheckout,
12281
- ) {
12282
- if (!replay.eventBuffer) {
12283
- // This implies that `_isEnabled` is false
12284
- return null;
12285
- }
12286
-
12287
- if (replay.isPaused()) {
12288
- // Do not add to event buffer when recording is paused
12289
- return null;
12290
- }
12291
-
12292
- const timestampInMs = timestampToMs(event.timestamp);
12293
-
12294
- // Throw out events that happen more than 5 minutes ago. This can happen if
12295
- // page has been left open and idle for a long period of time and user
12296
- // comes back to trigger a new session. The performance entries rely on
12297
- // `performance.timeOrigin`, which is when the page first opened.
12298
- if (timestampInMs + replay.timeouts.sessionIdlePause < Date.now()) {
12299
- return null;
12300
- }
12301
-
12302
- try {
12303
- if (isCheckout) {
12304
- replay.eventBuffer.clear();
12305
- }
12306
-
12307
- return await replay.eventBuffer.addEvent(event);
12308
- } catch (error) {
12309
- (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.error(error);
12310
- await replay.stop('addEvent');
12311
-
12312
- const client = getCurrentHub().getClient();
12313
-
12314
- if (client) {
12315
- client.recordDroppedEvent('internal_sdk_error', 'replay');
12316
- }
12317
- }
12318
- }
12319
-
12320
12735
  /** If the event is an error event */
12321
12736
  function isErrorEvent(event) {
12322
12737
  return !event.type;
@@ -12402,187 +12817,6 @@ function isBaseTransportSend() {
12402
12817
  );
12403
12818
  }
12404
12819
 
12405
- var NodeType;
12406
- (function (NodeType) {
12407
- NodeType[NodeType["Document"] = 0] = "Document";
12408
- NodeType[NodeType["DocumentType"] = 1] = "DocumentType";
12409
- NodeType[NodeType["Element"] = 2] = "Element";
12410
- NodeType[NodeType["Text"] = 3] = "Text";
12411
- NodeType[NodeType["CDATA"] = 4] = "CDATA";
12412
- NodeType[NodeType["Comment"] = 5] = "Comment";
12413
- })(NodeType || (NodeType = {}));
12414
-
12415
- /**
12416
- * Create a breadcrumb for a replay.
12417
- */
12418
- function createBreadcrumb(
12419
- breadcrumb,
12420
- ) {
12421
- return {
12422
- timestamp: Date.now() / 1000,
12423
- type: 'default',
12424
- ...breadcrumb,
12425
- };
12426
- }
12427
-
12428
- /**
12429
- * Add a breadcrumb event to replay.
12430
- */
12431
- function addBreadcrumbEvent(replay, breadcrumb) {
12432
- if (breadcrumb.category === 'sentry.transaction') {
12433
- return;
12434
- }
12435
-
12436
- if (['ui.click', 'ui.input'].includes(breadcrumb.category )) {
12437
- replay.triggerUserActivity();
12438
- } else {
12439
- replay.checkAndHandleExpiredSession();
12440
- }
12441
-
12442
- replay.addUpdate(() => {
12443
- void addEvent(replay, {
12444
- type: EventType$1.Custom,
12445
- // TODO: We were converting from ms to seconds for breadcrumbs, spans,
12446
- // but maybe we should just keep them as milliseconds
12447
- timestamp: (breadcrumb.timestamp || 0) * 1000,
12448
- data: {
12449
- tag: 'breadcrumb',
12450
- // normalize to max. 10 depth and 1_000 properties per object
12451
- payload: normalize(breadcrumb, 10, 1000),
12452
- },
12453
- });
12454
-
12455
- // Do not flush after console log messages
12456
- return breadcrumb.category === 'console';
12457
- });
12458
- }
12459
-
12460
- // Note that these are the serialized attributes and not attributes directly on
12461
- // the DOM Node. Attributes we are interested in:
12462
- const ATTRIBUTES_TO_RECORD = new Set([
12463
- 'id',
12464
- 'class',
12465
- 'aria-label',
12466
- 'role',
12467
- 'name',
12468
- 'alt',
12469
- 'title',
12470
- 'data-test-id',
12471
- 'data-testid',
12472
- ]);
12473
-
12474
- /**
12475
- * Inclusion list of attributes that we want to record from the DOM element
12476
- */
12477
- function getAttributesToRecord(attributes) {
12478
- const obj = {};
12479
- for (const key in attributes) {
12480
- if (ATTRIBUTES_TO_RECORD.has(key)) {
12481
- let normalizedKey = key;
12482
-
12483
- if (key === 'data-testid' || key === 'data-test-id') {
12484
- normalizedKey = 'testId';
12485
- }
12486
-
12487
- obj[normalizedKey] = attributes[key];
12488
- }
12489
- }
12490
-
12491
- return obj;
12492
- }
12493
-
12494
- const handleDomListener =
12495
- (replay) =>
12496
- (handlerData) => {
12497
- if (!replay.isEnabled()) {
12498
- return;
12499
- }
12500
-
12501
- const result = handleDom(handlerData);
12502
-
12503
- if (!result) {
12504
- return;
12505
- }
12506
-
12507
- addBreadcrumbEvent(replay, result);
12508
- };
12509
-
12510
- /**
12511
- * An event handler to react to DOM events.
12512
- * Exported for tests only.
12513
- */
12514
- function handleDom(handlerData) {
12515
- let target;
12516
- let targetNode;
12517
-
12518
- const isClick = handlerData.name === 'click';
12519
-
12520
- // Accessing event.target can throw (see getsentry/raven-js#838, #768)
12521
- try {
12522
- targetNode = isClick ? getClickTargetNode(handlerData.event) : getTargetNode(handlerData.event);
12523
- target = htmlTreeAsString(targetNode, { maxStringLength: 200 });
12524
- } catch (e) {
12525
- target = '<unknown>';
12526
- }
12527
-
12528
- // `__sn` property is the serialized node created by rrweb
12529
- const serializedNode =
12530
- targetNode && '__sn' in targetNode && targetNode.__sn.type === NodeType.Element ? targetNode.__sn : null;
12531
-
12532
- return createBreadcrumb({
12533
- category: `ui.${handlerData.name}`,
12534
- message: target,
12535
- data: serializedNode
12536
- ? {
12537
- nodeId: serializedNode.id,
12538
- node: {
12539
- id: serializedNode.id,
12540
- tagName: serializedNode.tagName,
12541
- textContent: targetNode
12542
- ? Array.from(targetNode.childNodes)
12543
- .map(
12544
- (node) => '__sn' in node && node.__sn.type === NodeType.Text && node.__sn.textContent,
12545
- )
12546
- .filter(Boolean) // filter out empty values
12547
- .map(text => (text ).trim())
12548
- .join('')
12549
- : '',
12550
- attributes: getAttributesToRecord(serializedNode.attributes),
12551
- },
12552
- }
12553
- : {},
12554
- });
12555
- }
12556
-
12557
- function getTargetNode(event) {
12558
- if (isEventWithTarget(event)) {
12559
- return event.target;
12560
- }
12561
-
12562
- return event;
12563
- }
12564
-
12565
- const INTERACTIVE_SELECTOR = 'button,a';
12566
-
12567
- // For clicks, we check if the target is inside of a button or link
12568
- // If so, we use this as the target instead
12569
- // This is useful because if you click on the image in <button><img></button>,
12570
- // The target will be the image, not the button, which we don't want here
12571
- function getClickTargetNode(event) {
12572
- const target = getTargetNode(event);
12573
-
12574
- if (!target || !(target instanceof Element)) {
12575
- return target;
12576
- }
12577
-
12578
- const closestInteractive = target.closest(INTERACTIVE_SELECTOR);
12579
- return closestInteractive || target;
12580
- }
12581
-
12582
- function isEventWithTarget(event) {
12583
- return !!(event ).target;
12584
- }
12585
-
12586
12820
  /**
12587
12821
  * Returns true if we think the given event is an error originating inside of rrweb.
12588
12822
  */
@@ -13500,7 +13734,32 @@ function _strIsProbablyJson(str) {
13500
13734
 
13501
13735
  /** Match an URL against a list of strings/Regex. */
13502
13736
  function urlMatches(url, urls) {
13503
- return stringMatchesSomePattern(url, urls);
13737
+ const fullUrl = getFullUrl(url);
13738
+
13739
+ return stringMatchesSomePattern(fullUrl, urls);
13740
+ }
13741
+
13742
+ /** exported for tests */
13743
+ function getFullUrl(url, baseURI = WINDOW.document.baseURI) {
13744
+ // Short circuit for common cases:
13745
+ if (url.startsWith('http://') || url.startsWith('https://') || url.startsWith(WINDOW.location.origin)) {
13746
+ return url;
13747
+ }
13748
+ const fixedUrl = new URL(url, baseURI);
13749
+
13750
+ // If these do not match, we are not dealing with a relative URL, so just return it
13751
+ if (fixedUrl.origin !== new URL(baseURI).origin) {
13752
+ return url;
13753
+ }
13754
+
13755
+ const fullUrl = fixedUrl.href;
13756
+
13757
+ // Remove trailing slashes, if they don't match the original URL
13758
+ if (!url.endsWith('/') && fullUrl.endsWith('/')) {
13759
+ return fullUrl.slice(0, -1);
13760
+ }
13761
+
13762
+ return fullUrl;
13504
13763
  }
13505
13764
 
13506
13765
  /**
@@ -15425,8 +15684,8 @@ class ReplayContainer {
15425
15684
  };}
15426
15685
 
15427
15686
  /** Ensure page remains active when a key is pressed. */
15428
- __init16() {this._handleKeyboardEvent = () => {
15429
- this.triggerUserActivity();
15687
+ __init16() {this._handleKeyboardEvent = (event) => {
15688
+ handleKeyboardEvent(this, event);
15430
15689
  };}
15431
15690
 
15432
15691
  /**
@@ -30095,7 +30354,12 @@ const DEVICE = {
30095
30354
  PLATFORM: PLATFORMS_OPTIONS.find((p) => { var _a, _b; return (_b = (_a = platform.os) === null || _a === void 0 ? void 0 : _a.family) === null || _b === void 0 ? void 0 : _b.toUpperCase().includes(p === 'MACBOOK' ? 'OS X' : p); }) || 'WINDOWS',
30096
30355
  BROWSER: BROWSERS_OPTIONS.find((b) => { var _a; return (_a = platform.name) === null || _a === void 0 ? void 0 : _a.toUpperCase().includes(b); }) || 'CHROME',
30097
30356
  };
30098
- const isPortrait = () => !screen.orientation.type.startsWith('landscape');
30357
+ const isPortrait = () => {
30358
+ if (typeof window.matchMedia !== 'undefined') {
30359
+ return window.matchMedia('(orientation: portrait)').matches;
30360
+ }
30361
+ return window.innerHeight > window.innerWidth;
30362
+ };
30099
30363
  const iPhoneModels = [
30100
30364
  { pixelRatio: 2, width: 640, height: 1136, model: 'iPhone SE (1st generation)' },
30101
30365
  { pixelRatio: 2, width: 750, height: 1334, model: 'iPhone SE (2nd generation)/6/6S/7/8' },