@glimt/record 0.0.59 → 0.0.61

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/record.cjs CHANGED
@@ -1001,6 +1001,223 @@ const _AsyncStylesheetManager$1 = class _AsyncStylesheetManager {
1001
1001
  __publicField$1(_AsyncStylesheetManager$1, "instance");
1002
1002
  let AsyncStylesheetManager$1 = _AsyncStylesheetManager$1;
1003
1003
  const asyncStylesheetManager$1 = new AsyncStylesheetManager$1();
1004
+ const serializeLinkInline = ({
1005
+ attributes,
1006
+ doc,
1007
+ n: n2
1008
+ }) => {
1009
+ const styleSheets2 = Array.from(doc.styleSheets);
1010
+ let stylesheet = null;
1011
+ for (let i2 = 0; i2 < styleSheets2.length; i2++) {
1012
+ if (styleSheets2[i2].href === n2.href) {
1013
+ stylesheet = styleSheets2[i2];
1014
+ break;
1015
+ }
1016
+ }
1017
+ let cssText = null;
1018
+ if (stylesheet) {
1019
+ cssText = stringifyStylesheet$1(stylesheet);
1020
+ }
1021
+ if (!cssText) {
1022
+ cssText = asyncStylesheetManager$1.getClonedCssTextIfAvailable(
1023
+ n2.href
1024
+ );
1025
+ }
1026
+ if (cssText) {
1027
+ delete attributes.rel;
1028
+ delete attributes.href;
1029
+ attributes._cssText = cssText;
1030
+ } else {
1031
+ const requestCssId = `css-request-${Math.random().toString(36).slice(2)}`;
1032
+ asyncStylesheetManager$1.requestClone({
1033
+ forElement: n2,
1034
+ requestCssId
1035
+ });
1036
+ attributes._requestCssId = requestCssId;
1037
+ }
1038
+ return attributes;
1039
+ };
1040
+ const serializeStyleInline = ({
1041
+ attributes,
1042
+ n: n2
1043
+ }) => {
1044
+ let cssText = stringifyStylesheet$1(
1045
+ n2.sheet
1046
+ );
1047
+ if (cssText) {
1048
+ if (n2.childNodes.length > 1) {
1049
+ cssText = markCssSplits(cssText, n2);
1050
+ }
1051
+ attributes._cssText = cssText;
1052
+ }
1053
+ return attributes;
1054
+ };
1055
+ const serializeUserFields = ({
1056
+ attributes,
1057
+ n: n2,
1058
+ tagName,
1059
+ maskInputOptions,
1060
+ maskInputFn
1061
+ }) => {
1062
+ const value = n2.value;
1063
+ const checked = n2.checked;
1064
+ if (attributes.type !== "radio" && attributes.type !== "checkbox" && attributes.type !== "submit" && attributes.type !== "button" && value) {
1065
+ attributes.value = maskInputValue({
1066
+ element: n2,
1067
+ type: getInputType(n2),
1068
+ tagName,
1069
+ value,
1070
+ maskInputOptions,
1071
+ maskInputFn
1072
+ });
1073
+ } else if (checked) {
1074
+ attributes.checked = checked;
1075
+ }
1076
+ return attributes;
1077
+ };
1078
+ const serializeOption = ({
1079
+ attributes,
1080
+ n: n2,
1081
+ maskInputOptions
1082
+ }) => {
1083
+ if (n2.selected && !maskInputOptions["select"]) {
1084
+ attributes.selected = true;
1085
+ } else {
1086
+ delete attributes.selected;
1087
+ }
1088
+ return attributes;
1089
+ };
1090
+ const runIdleCallback = (cb) => {
1091
+ if ("requestIdleCallback" in window) {
1092
+ window.requestIdleCallback(cb);
1093
+ } else {
1094
+ setTimeout(cb, 100);
1095
+ }
1096
+ };
1097
+ const serializeCanvas = ({
1098
+ attributes,
1099
+ n: n2,
1100
+ dataURLOptions,
1101
+ doc
1102
+ }) => {
1103
+ let context = "getContext" in n2 ? n2.getContext("2d") : null;
1104
+ if (context != null) {
1105
+ if (!is2DCanvasBlank(n2, context)) {
1106
+ attributes.rr_dataURL = n2.toDataURL(
1107
+ dataURLOptions.type,
1108
+ dataURLOptions.quality
1109
+ );
1110
+ }
1111
+ } else if (n2.width !== 0 && n2.height !== 0) {
1112
+ const canvasDataURL = n2.toDataURL(
1113
+ dataURLOptions.type,
1114
+ dataURLOptions.quality
1115
+ );
1116
+ attributes.rr_dataURL = canvasDataURL;
1117
+ runIdleCallback(() => {
1118
+ try {
1119
+ const blankCanvas = doc.createElement("canvas");
1120
+ blankCanvas.width = n2.width;
1121
+ blankCanvas.height = n2.height;
1122
+ const blankCanvasDataURL = blankCanvas.toDataURL(
1123
+ dataURLOptions.type,
1124
+ dataURLOptions.quality
1125
+ );
1126
+ if (canvasDataURL === blankCanvasDataURL) {
1127
+ delete attributes.rr_dataURL;
1128
+ }
1129
+ } catch (e2) {
1130
+ }
1131
+ });
1132
+ }
1133
+ return attributes;
1134
+ };
1135
+ const serializeImageInline = ({
1136
+ attributes,
1137
+ n: n2,
1138
+ canvasService: canvasService2,
1139
+ canvasCtx: canvasCtx2,
1140
+ dataURLOptions,
1141
+ doc
1142
+ }) => {
1143
+ if (!canvasService2) {
1144
+ canvasService2 = doc.createElement("canvas");
1145
+ canvasCtx2 = canvasService2.getContext("2d");
1146
+ }
1147
+ const image = n2;
1148
+ let overrideImage = null;
1149
+ let calls = 0;
1150
+ const imageSrc = (image.currentSrc || image.getAttribute("src") || "<unknown-src>") + "";
1151
+ const imageHeight = image.naturalHeight;
1152
+ const imageWidth = image.naturalWidth;
1153
+ const inlineImageCleanup = () => {
1154
+ overrideImage = null;
1155
+ };
1156
+ const recordInlineImage = () => {
1157
+ calls++;
1158
+ if (calls > 3) return;
1159
+ (overrideImage ?? image).removeEventListener("error", onImageLoadError);
1160
+ try {
1161
+ canvasService2.width = imageWidth;
1162
+ canvasService2.height = imageHeight;
1163
+ canvasCtx2.drawImage(image, 0, 0);
1164
+ attributes.rr_dataURL = canvasService2.toDataURL(
1165
+ dataURLOptions.type,
1166
+ dataURLOptions.quality
1167
+ );
1168
+ } catch (err) {
1169
+ if (image.crossOrigin !== "anonymous") {
1170
+ if (shouldTryAnonymousFetchingOnCorsError$1()) {
1171
+ overrideImage = new Image();
1172
+ overrideImage.src = imageSrc;
1173
+ overrideImage.crossOrigin = "anonymous";
1174
+ overrideImage.height = imageHeight;
1175
+ overrideImage.width = imageWidth;
1176
+ if (overrideImage.complete && overrideImage.naturalWidth !== 0) {
1177
+ recordInlineImage();
1178
+ } else {
1179
+ overrideImage.addEventListener("load", recordInlineImage, {
1180
+ once: true
1181
+ });
1182
+ overrideImage.addEventListener("error", onImageLoadError, {
1183
+ once: true
1184
+ });
1185
+ }
1186
+ return;
1187
+ }
1188
+ } else {
1189
+ if (isDebug$1())
1190
+ console.warn(
1191
+ `Cannot inline img src=${imageSrc}! Error: ${err}`
1192
+ );
1193
+ }
1194
+ }
1195
+ inlineImageCleanup();
1196
+ };
1197
+ const onImageLoadError = () => {
1198
+ (overrideImage ?? image).removeEventListener("load", recordInlineImage);
1199
+ inlineImageCleanup();
1200
+ };
1201
+ if (image.complete && image.naturalWidth !== 0) recordInlineImage();
1202
+ else {
1203
+ image.addEventListener("load", recordInlineImage, { once: true });
1204
+ image.addEventListener("error", onImageLoadError, { once: true });
1205
+ }
1206
+ return attributes;
1207
+ };
1208
+ const serializeMediaElements = ({
1209
+ attributes,
1210
+ n: n2
1211
+ }) => {
1212
+ const mediaAttributes = attributes;
1213
+ mediaAttributes.rr_mediaState = n2.paused ? "paused" : "played";
1214
+ mediaAttributes.rr_mediaCurrentTime = n2.currentTime;
1215
+ mediaAttributes.rr_mediaPlaybackRate = n2.playbackRate;
1216
+ mediaAttributes.rr_mediaMuted = n2.muted;
1217
+ mediaAttributes.rr_mediaLoop = n2.loop;
1218
+ mediaAttributes.rr_mediaVolume = n2.volume;
1219
+ return attributes;
1220
+ };
1004
1221
  let _id = 1;
1005
1222
  const tagNameRegex = new RegExp("[^a-z0-9-_:]");
1006
1223
  const IGNORED_NODE = -2;
@@ -1017,8 +1234,8 @@ function getValidTagName$1(element) {
1017
1234
  }
1018
1235
  return processedTagName;
1019
1236
  }
1020
- let canvasService;
1021
- let canvasCtx;
1237
+ let canvasService = null;
1238
+ let canvasCtx = null;
1022
1239
  const SRCSET_NOT_SPACES = /^[^ \t\n\r\u000c]+/;
1023
1240
  const SRCSET_COMMAS_OR_SPACES = /^[, \t\n\r\u000c]+/;
1024
1241
  function getAbsoluteSrcsetString(doc, attributeValue) {
@@ -1330,13 +1547,6 @@ function getRootId(doc, mirror2) {
1330
1547
  const docId = mirror2.getId(doc);
1331
1548
  return docId === 1 ? void 0 : docId;
1332
1549
  }
1333
- const runIdleCallback = (cb) => {
1334
- if ("requestIdleCallback" in window) {
1335
- window.requestIdleCallback(cb);
1336
- } else {
1337
- setTimeout(cb, 100);
1338
- }
1339
- };
1340
1550
  function serializeTextNode(n2, options) {
1341
1551
  const { needsMask, maskTextFn, rootId, cssCaptured } = options;
1342
1552
  const parent = index.parentNode(n2);
@@ -1391,179 +1601,77 @@ function serializeElementNode(n2, options) {
1391
1601
  );
1392
1602
  }
1393
1603
  }
1394
- if (tagName === "link" && inlineStylesheet) {
1395
- const styleSheets2 = Array.from(doc.styleSheets);
1396
- let stylesheet = null;
1397
- for (let i2 = 0; i2 < styleSheets2.length; i2++) {
1398
- if (styleSheets2[i2].href === n2.href) {
1399
- stylesheet = styleSheets2[i2];
1400
- break;
1604
+ switch (tagName) {
1605
+ case "link":
1606
+ if (inlineStylesheet) {
1607
+ attributes = serializeLinkInline({
1608
+ doc,
1609
+ attributes,
1610
+ n: n2
1611
+ });
1401
1612
  }
1402
- }
1403
- let cssText = null;
1404
- if (stylesheet) {
1405
- cssText = stringifyStylesheet$1(stylesheet);
1406
- }
1407
- if (!cssText) {
1408
- cssText = asyncStylesheetManager$1.getClonedCssTextIfAvailable(
1409
- n2.href
1410
- );
1411
- }
1412
- if (cssText) {
1413
- delete attributes.rel;
1414
- delete attributes.href;
1415
- attributes._cssText = cssText;
1416
- } else {
1417
- const requestCssId = `css-request-${Math.random().toString(36).slice(2)}`;
1418
- asyncStylesheetManager$1.requestClone({
1419
- forElement: n2,
1420
- requestCssId
1421
- });
1422
- attributes._requestCssId = requestCssId;
1423
- }
1424
- }
1425
- if (tagName === "style" && n2.sheet) {
1426
- let cssText = stringifyStylesheet$1(
1427
- n2.sheet
1428
- );
1429
- if (cssText) {
1430
- if (n2.childNodes.length > 1) {
1431
- cssText = markCssSplits(cssText, n2);
1613
+ break;
1614
+ case "style":
1615
+ if (n2.sheet) {
1616
+ attributes = serializeStyleInline({
1617
+ attributes,
1618
+ n: n2
1619
+ });
1432
1620
  }
1433
- attributes._cssText = cssText;
1434
- }
1435
- }
1436
- if (tagName === "input" || tagName === "textarea" || tagName === "select") {
1437
- const value = n2.value;
1438
- const checked = n2.checked;
1439
- if (attributes.type !== "radio" && attributes.type !== "checkbox" && attributes.type !== "submit" && attributes.type !== "button" && value) {
1440
- attributes.value = maskInputValue({
1441
- element: n2,
1442
- type: getInputType(n2),
1621
+ break;
1622
+ case "input":
1623
+ case "textarea":
1624
+ case "select":
1625
+ attributes = serializeUserFields({
1626
+ attributes,
1627
+ n: n2,
1443
1628
  tagName,
1444
- value,
1445
1629
  maskInputOptions,
1446
1630
  maskInputFn
1447
1631
  });
1448
- } else if (checked) {
1449
- attributes.checked = checked;
1450
- }
1451
- }
1452
- if (tagName === "option") {
1453
- if (n2.selected && !maskInputOptions["select"]) {
1454
- attributes.selected = true;
1455
- } else {
1456
- delete attributes.selected;
1457
- }
1458
- }
1459
- if (tagName === "dialog" && n2.open) {
1460
- attributes.rr_open_mode = n2.matches("dialog:modal") ? "modal" : "non-modal";
1461
- }
1462
- if (tagName === "canvas" && recordCanvas) {
1463
- let context = "getContext" in n2 ? n2.getContext("2d") : null;
1464
- if (context != null) {
1465
- if (!is2DCanvasBlank(n2, context)) {
1466
- attributes.rr_dataURL = n2.toDataURL(
1467
- dataURLOptions.type,
1468
- dataURLOptions.quality
1469
- );
1470
- }
1471
- } else if (n2.width !== 0 && n2.height !== 0) {
1472
- const canvasDataURL = n2.toDataURL(
1473
- dataURLOptions.type,
1474
- dataURLOptions.quality
1475
- );
1476
- attributes.rr_dataURL = canvasDataURL;
1477
- runIdleCallback(() => {
1478
- try {
1479
- const blankCanvas = doc.createElement("canvas");
1480
- blankCanvas.width = n2.width;
1481
- blankCanvas.height = n2.height;
1482
- const blankCanvasDataURL = blankCanvas.toDataURL(
1483
- dataURLOptions.type,
1484
- dataURLOptions.quality
1485
- );
1486
- if (canvasDataURL === blankCanvasDataURL) {
1487
- delete attributes.rr_dataURL;
1488
- }
1489
- } catch (e2) {
1490
- }
1632
+ break;
1633
+ case "option":
1634
+ attributes = serializeOption({
1635
+ attributes,
1636
+ n: n2,
1637
+ maskInputOptions
1491
1638
  });
1492
- }
1493
- }
1494
- if (tagName === "img" && inlineImages) {
1495
- if (!canvasService) {
1496
- canvasService = doc.createElement("canvas");
1497
- canvasCtx = canvasService.getContext("2d");
1498
- }
1499
- const image = n2;
1500
- let overrideImage = null;
1501
- let calls = 0;
1502
- const imageSrc = (image.currentSrc || image.getAttribute("src") || "<unknown-src>") + "";
1503
- const imageHeight = image.naturalHeight;
1504
- const imageWidth = image.naturalWidth;
1505
- const inlineImageCleanup = () => {
1506
- overrideImage = null;
1507
- };
1508
- const recordInlineImage = () => {
1509
- calls++;
1510
- if (calls > 3) return;
1511
- (overrideImage ?? image).removeEventListener("error", onImageLoadError);
1512
- try {
1513
- canvasService.width = imageWidth;
1514
- canvasService.height = imageHeight;
1515
- canvasCtx.drawImage(image, 0, 0);
1516
- attributes.rr_dataURL = canvasService.toDataURL(
1517
- dataURLOptions.type,
1518
- dataURLOptions.quality
1519
- );
1520
- } catch (err) {
1521
- if (image.crossOrigin !== "anonymous") {
1522
- if (shouldTryAnonymousFetchingOnCorsError$1()) {
1523
- overrideImage = new Image();
1524
- overrideImage.src = imageSrc;
1525
- overrideImage.crossOrigin = "anonymous";
1526
- overrideImage.height = imageHeight;
1527
- overrideImage.width = imageWidth;
1528
- if (overrideImage.complete && overrideImage.naturalWidth !== 0) {
1529
- recordInlineImage();
1530
- } else {
1531
- overrideImage.addEventListener("load", recordInlineImage, {
1532
- once: true
1533
- });
1534
- overrideImage.addEventListener("error", onImageLoadError, {
1535
- once: true
1536
- });
1537
- }
1538
- return;
1539
- }
1540
- } else {
1541
- if (isDebug$1())
1542
- console.warn(
1543
- `Cannot inline img src=${imageSrc}! Error: ${err}`
1544
- );
1545
- }
1639
+ break;
1640
+ case "dialog":
1641
+ if (n2.open) {
1642
+ attributes.rr_open_mode = n2.matches(
1643
+ "dialog:modal"
1644
+ ) ? "modal" : "non-modal";
1546
1645
  }
1547
- inlineImageCleanup();
1548
- };
1549
- const onImageLoadError = () => {
1550
- (overrideImage ?? image).removeEventListener("load", recordInlineImage);
1551
- inlineImageCleanup();
1552
- };
1553
- if (image.complete && image.naturalWidth !== 0) recordInlineImage();
1554
- else {
1555
- image.addEventListener("load", recordInlineImage, { once: true });
1556
- image.addEventListener("error", onImageLoadError, { once: true });
1557
- }
1558
- }
1559
- if (tagName === "audio" || tagName === "video") {
1560
- const mediaAttributes = attributes;
1561
- mediaAttributes.rr_mediaState = n2.paused ? "paused" : "played";
1562
- mediaAttributes.rr_mediaCurrentTime = n2.currentTime;
1563
- mediaAttributes.rr_mediaPlaybackRate = n2.playbackRate;
1564
- mediaAttributes.rr_mediaMuted = n2.muted;
1565
- mediaAttributes.rr_mediaLoop = n2.loop;
1566
- mediaAttributes.rr_mediaVolume = n2.volume;
1646
+ break;
1647
+ case "canvas":
1648
+ if (recordCanvas) {
1649
+ attributes = serializeCanvas({
1650
+ attributes,
1651
+ n: n2,
1652
+ dataURLOptions,
1653
+ doc
1654
+ });
1655
+ }
1656
+ case "img":
1657
+ if (inlineImages) {
1658
+ attributes = serializeImageInline({
1659
+ attributes,
1660
+ n: n2,
1661
+ canvasService,
1662
+ canvasCtx,
1663
+ dataURLOptions,
1664
+ doc
1665
+ });
1666
+ }
1667
+ break;
1668
+ case "audio":
1669
+ case "video":
1670
+ attributes = serializeMediaElements({
1671
+ attributes,
1672
+ n: n2
1673
+ });
1674
+ break;
1567
1675
  }
1568
1676
  if (!newlyAddedElement) {
1569
1677
  if (n2.scrollLeft) {
@@ -1883,15 +1991,17 @@ function serializeNodeWithId(n2, options) {
1883
1991
  debugging.store[n2.nodeName] = [];
1884
1992
  }
1885
1993
  debugging.store[n2.nodeName].push(took);
1886
- if (debugging.index % 100 === 0) {
1994
+ if (debugging.index % 1e3 === 0) {
1887
1995
  debugging.index = 0;
1888
1996
  const avgs = Object.entries(debugging.store).map(([key, values]) => {
1889
1997
  return {
1890
1998
  key,
1891
- avg: values.reduce((a2, b) => a2 + b, 0) / values.length
1999
+ avg: values.reduce((a2, b) => a2 + b, 0) / values.length,
2000
+ max: Math.max(...values),
2001
+ min: Math.min(...values)
1892
2002
  };
1893
2003
  });
1894
- console.log("last 100 avgs", JSON.parse(JSON.stringify(avgs)));
2004
+ console.log("last 1000 avgs", JSON.parse(JSON.stringify(avgs)));
1895
2005
  debugging.store = {};
1896
2006
  }
1897
2007
  return serializedNode;