@glimt/record 0.0.59 → 0.0.60

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.
@@ -1034,6 +1034,223 @@ const _AsyncStylesheetManager$1 = class _AsyncStylesheetManager {
1034
1034
  __publicField$1(_AsyncStylesheetManager$1, "instance");
1035
1035
  let AsyncStylesheetManager$1 = _AsyncStylesheetManager$1;
1036
1036
  const asyncStylesheetManager$1 = new AsyncStylesheetManager$1();
1037
+ const serializeLinkInline = ({
1038
+ attributes,
1039
+ doc,
1040
+ n: n2
1041
+ }) => {
1042
+ const styleSheets2 = Array.from(doc.styleSheets);
1043
+ let stylesheet = null;
1044
+ for (let i2 = 0; i2 < styleSheets2.length; i2++) {
1045
+ if (styleSheets2[i2].href === n2.href) {
1046
+ stylesheet = styleSheets2[i2];
1047
+ break;
1048
+ }
1049
+ }
1050
+ let cssText = null;
1051
+ if (stylesheet) {
1052
+ cssText = stringifyStylesheet$1(stylesheet);
1053
+ }
1054
+ if (!cssText) {
1055
+ cssText = asyncStylesheetManager$1.getClonedCssTextIfAvailable(
1056
+ n2.href
1057
+ );
1058
+ }
1059
+ if (cssText) {
1060
+ delete attributes.rel;
1061
+ delete attributes.href;
1062
+ attributes._cssText = cssText;
1063
+ } else {
1064
+ const requestCssId = `css-request-${Math.random().toString(36).slice(2)}`;
1065
+ asyncStylesheetManager$1.requestClone({
1066
+ forElement: n2,
1067
+ requestCssId
1068
+ });
1069
+ attributes._requestCssId = requestCssId;
1070
+ }
1071
+ return attributes;
1072
+ };
1073
+ const serializeStyleInline = ({
1074
+ attributes,
1075
+ n: n2
1076
+ }) => {
1077
+ let cssText = stringifyStylesheet$1(
1078
+ n2.sheet
1079
+ );
1080
+ if (cssText) {
1081
+ if (n2.childNodes.length > 1) {
1082
+ cssText = markCssSplits(cssText, n2);
1083
+ }
1084
+ attributes._cssText = cssText;
1085
+ }
1086
+ return attributes;
1087
+ };
1088
+ const serializeUserFields = ({
1089
+ attributes,
1090
+ n: n2,
1091
+ tagName,
1092
+ maskInputOptions,
1093
+ maskInputFn
1094
+ }) => {
1095
+ const value = n2.value;
1096
+ const checked = n2.checked;
1097
+ if (attributes.type !== "radio" && attributes.type !== "checkbox" && attributes.type !== "submit" && attributes.type !== "button" && value) {
1098
+ attributes.value = maskInputValue({
1099
+ element: n2,
1100
+ type: getInputType(n2),
1101
+ tagName,
1102
+ value,
1103
+ maskInputOptions,
1104
+ maskInputFn
1105
+ });
1106
+ } else if (checked) {
1107
+ attributes.checked = checked;
1108
+ }
1109
+ return attributes;
1110
+ };
1111
+ const serializeOption = ({
1112
+ attributes,
1113
+ n: n2,
1114
+ maskInputOptions
1115
+ }) => {
1116
+ if (n2.selected && !maskInputOptions["select"]) {
1117
+ attributes.selected = true;
1118
+ } else {
1119
+ delete attributes.selected;
1120
+ }
1121
+ return attributes;
1122
+ };
1123
+ const runIdleCallback = (cb) => {
1124
+ if ("requestIdleCallback" in window) {
1125
+ window.requestIdleCallback(cb);
1126
+ } else {
1127
+ setTimeout(cb, 100);
1128
+ }
1129
+ };
1130
+ const serializeCanvas = ({
1131
+ attributes,
1132
+ n: n2,
1133
+ dataURLOptions,
1134
+ doc
1135
+ }) => {
1136
+ let context = "getContext" in n2 ? n2.getContext("2d") : null;
1137
+ if (context != null) {
1138
+ if (!is2DCanvasBlank(n2, context)) {
1139
+ attributes.rr_dataURL = n2.toDataURL(
1140
+ dataURLOptions.type,
1141
+ dataURLOptions.quality
1142
+ );
1143
+ }
1144
+ } else if (n2.width !== 0 && n2.height !== 0) {
1145
+ const canvasDataURL = n2.toDataURL(
1146
+ dataURLOptions.type,
1147
+ dataURLOptions.quality
1148
+ );
1149
+ attributes.rr_dataURL = canvasDataURL;
1150
+ runIdleCallback(() => {
1151
+ try {
1152
+ const blankCanvas = doc.createElement("canvas");
1153
+ blankCanvas.width = n2.width;
1154
+ blankCanvas.height = n2.height;
1155
+ const blankCanvasDataURL = blankCanvas.toDataURL(
1156
+ dataURLOptions.type,
1157
+ dataURLOptions.quality
1158
+ );
1159
+ if (canvasDataURL === blankCanvasDataURL) {
1160
+ delete attributes.rr_dataURL;
1161
+ }
1162
+ } catch (e2) {
1163
+ }
1164
+ });
1165
+ }
1166
+ return attributes;
1167
+ };
1168
+ const serializeImageInline = ({
1169
+ attributes,
1170
+ n: n2,
1171
+ canvasService: canvasService2,
1172
+ canvasCtx: canvasCtx2,
1173
+ dataURLOptions,
1174
+ doc
1175
+ }) => {
1176
+ if (!canvasService2) {
1177
+ canvasService2 = doc.createElement("canvas");
1178
+ canvasCtx2 = canvasService2.getContext("2d");
1179
+ }
1180
+ const image = n2;
1181
+ let overrideImage = null;
1182
+ let calls = 0;
1183
+ const imageSrc = (image.currentSrc || image.getAttribute("src") || "<unknown-src>") + "";
1184
+ const imageHeight = image.naturalHeight;
1185
+ const imageWidth = image.naturalWidth;
1186
+ const inlineImageCleanup = () => {
1187
+ overrideImage = null;
1188
+ };
1189
+ const recordInlineImage = () => {
1190
+ calls++;
1191
+ if (calls > 3) return;
1192
+ (overrideImage != null ? overrideImage : image).removeEventListener("error", onImageLoadError);
1193
+ try {
1194
+ canvasService2.width = imageWidth;
1195
+ canvasService2.height = imageHeight;
1196
+ canvasCtx2.drawImage(image, 0, 0);
1197
+ attributes.rr_dataURL = canvasService2.toDataURL(
1198
+ dataURLOptions.type,
1199
+ dataURLOptions.quality
1200
+ );
1201
+ } catch (err) {
1202
+ if (image.crossOrigin !== "anonymous") {
1203
+ if (shouldTryAnonymousFetchingOnCorsError$1()) {
1204
+ overrideImage = new Image();
1205
+ overrideImage.src = imageSrc;
1206
+ overrideImage.crossOrigin = "anonymous";
1207
+ overrideImage.height = imageHeight;
1208
+ overrideImage.width = imageWidth;
1209
+ if (overrideImage.complete && overrideImage.naturalWidth !== 0) {
1210
+ recordInlineImage();
1211
+ } else {
1212
+ overrideImage.addEventListener("load", recordInlineImage, {
1213
+ once: true
1214
+ });
1215
+ overrideImage.addEventListener("error", onImageLoadError, {
1216
+ once: true
1217
+ });
1218
+ }
1219
+ return;
1220
+ }
1221
+ } else {
1222
+ if (isDebug$1())
1223
+ console.warn(
1224
+ `Cannot inline img src=${imageSrc}! Error: ${err}`
1225
+ );
1226
+ }
1227
+ }
1228
+ inlineImageCleanup();
1229
+ };
1230
+ const onImageLoadError = () => {
1231
+ (overrideImage != null ? overrideImage : image).removeEventListener("load", recordInlineImage);
1232
+ inlineImageCleanup();
1233
+ };
1234
+ if (image.complete && image.naturalWidth !== 0) recordInlineImage();
1235
+ else {
1236
+ image.addEventListener("load", recordInlineImage, { once: true });
1237
+ image.addEventListener("error", onImageLoadError, { once: true });
1238
+ }
1239
+ return attributes;
1240
+ };
1241
+ const serializeMediaElements = ({
1242
+ attributes,
1243
+ n: n2
1244
+ }) => {
1245
+ const mediaAttributes = attributes;
1246
+ mediaAttributes.rr_mediaState = n2.paused ? "paused" : "played";
1247
+ mediaAttributes.rr_mediaCurrentTime = n2.currentTime;
1248
+ mediaAttributes.rr_mediaPlaybackRate = n2.playbackRate;
1249
+ mediaAttributes.rr_mediaMuted = n2.muted;
1250
+ mediaAttributes.rr_mediaLoop = n2.loop;
1251
+ mediaAttributes.rr_mediaVolume = n2.volume;
1252
+ return attributes;
1253
+ };
1037
1254
  let _id = 1;
1038
1255
  const tagNameRegex = new RegExp("[^a-z0-9-_:]");
1039
1256
  const IGNORED_NODE = -2;
@@ -1050,8 +1267,8 @@ function getValidTagName$1(element) {
1050
1267
  }
1051
1268
  return processedTagName;
1052
1269
  }
1053
- let canvasService;
1054
- let canvasCtx;
1270
+ let canvasService = null;
1271
+ let canvasCtx = null;
1055
1272
  const SRCSET_NOT_SPACES = /^[^ \t\n\r\u000c]+/;
1056
1273
  const SRCSET_COMMAS_OR_SPACES = /^[, \t\n\r\u000c]+/;
1057
1274
  function getAbsoluteSrcsetString(doc, attributeValue) {
@@ -1363,13 +1580,6 @@ function getRootId(doc, mirror2) {
1363
1580
  const docId = mirror2.getId(doc);
1364
1581
  return docId === 1 ? void 0 : docId;
1365
1582
  }
1366
- const runIdleCallback = (cb) => {
1367
- if ("requestIdleCallback" in window) {
1368
- window.requestIdleCallback(cb);
1369
- } else {
1370
- setTimeout(cb, 100);
1371
- }
1372
- };
1373
1583
  function serializeTextNode(n2, options) {
1374
1584
  const { needsMask, maskTextFn, rootId, cssCaptured } = options;
1375
1585
  const parent = index.parentNode(n2);
@@ -1424,179 +1634,77 @@ function serializeElementNode(n2, options) {
1424
1634
  );
1425
1635
  }
1426
1636
  }
1427
- if (tagName === "link" && inlineStylesheet) {
1428
- const styleSheets2 = Array.from(doc.styleSheets);
1429
- let stylesheet = null;
1430
- for (let i2 = 0; i2 < styleSheets2.length; i2++) {
1431
- if (styleSheets2[i2].href === n2.href) {
1432
- stylesheet = styleSheets2[i2];
1433
- break;
1637
+ switch (tagName) {
1638
+ case "link":
1639
+ if (inlineStylesheet) {
1640
+ attributes = serializeLinkInline({
1641
+ doc,
1642
+ attributes,
1643
+ n: n2
1644
+ });
1434
1645
  }
1435
- }
1436
- let cssText = null;
1437
- if (stylesheet) {
1438
- cssText = stringifyStylesheet$1(stylesheet);
1439
- }
1440
- if (!cssText) {
1441
- cssText = asyncStylesheetManager$1.getClonedCssTextIfAvailable(
1442
- n2.href
1443
- );
1444
- }
1445
- if (cssText) {
1446
- delete attributes.rel;
1447
- delete attributes.href;
1448
- attributes._cssText = cssText;
1449
- } else {
1450
- const requestCssId = `css-request-${Math.random().toString(36).slice(2)}`;
1451
- asyncStylesheetManager$1.requestClone({
1452
- forElement: n2,
1453
- requestCssId
1454
- });
1455
- attributes._requestCssId = requestCssId;
1456
- }
1457
- }
1458
- if (tagName === "style" && n2.sheet) {
1459
- let cssText = stringifyStylesheet$1(
1460
- n2.sheet
1461
- );
1462
- if (cssText) {
1463
- if (n2.childNodes.length > 1) {
1464
- cssText = markCssSplits(cssText, n2);
1646
+ break;
1647
+ case "style":
1648
+ if (n2.sheet) {
1649
+ attributes = serializeStyleInline({
1650
+ attributes,
1651
+ n: n2
1652
+ });
1465
1653
  }
1466
- attributes._cssText = cssText;
1467
- }
1468
- }
1469
- if (tagName === "input" || tagName === "textarea" || tagName === "select") {
1470
- const value = n2.value;
1471
- const checked = n2.checked;
1472
- if (attributes.type !== "radio" && attributes.type !== "checkbox" && attributes.type !== "submit" && attributes.type !== "button" && value) {
1473
- attributes.value = maskInputValue({
1474
- element: n2,
1475
- type: getInputType(n2),
1654
+ break;
1655
+ case "input":
1656
+ case "textarea":
1657
+ case "select":
1658
+ attributes = serializeUserFields({
1659
+ attributes,
1660
+ n: n2,
1476
1661
  tagName,
1477
- value,
1478
1662
  maskInputOptions,
1479
1663
  maskInputFn
1480
1664
  });
1481
- } else if (checked) {
1482
- attributes.checked = checked;
1483
- }
1484
- }
1485
- if (tagName === "option") {
1486
- if (n2.selected && !maskInputOptions["select"]) {
1487
- attributes.selected = true;
1488
- } else {
1489
- delete attributes.selected;
1490
- }
1491
- }
1492
- if (tagName === "dialog" && n2.open) {
1493
- attributes.rr_open_mode = n2.matches("dialog:modal") ? "modal" : "non-modal";
1494
- }
1495
- if (tagName === "canvas" && recordCanvas) {
1496
- let context = "getContext" in n2 ? n2.getContext("2d") : null;
1497
- if (context != null) {
1498
- if (!is2DCanvasBlank(n2, context)) {
1499
- attributes.rr_dataURL = n2.toDataURL(
1500
- dataURLOptions.type,
1501
- dataURLOptions.quality
1502
- );
1503
- }
1504
- } else if (n2.width !== 0 && n2.height !== 0) {
1505
- const canvasDataURL = n2.toDataURL(
1506
- dataURLOptions.type,
1507
- dataURLOptions.quality
1508
- );
1509
- attributes.rr_dataURL = canvasDataURL;
1510
- runIdleCallback(() => {
1511
- try {
1512
- const blankCanvas = doc.createElement("canvas");
1513
- blankCanvas.width = n2.width;
1514
- blankCanvas.height = n2.height;
1515
- const blankCanvasDataURL = blankCanvas.toDataURL(
1516
- dataURLOptions.type,
1517
- dataURLOptions.quality
1518
- );
1519
- if (canvasDataURL === blankCanvasDataURL) {
1520
- delete attributes.rr_dataURL;
1521
- }
1522
- } catch (e2) {
1523
- }
1665
+ break;
1666
+ case "option":
1667
+ attributes = serializeOption({
1668
+ attributes,
1669
+ n: n2,
1670
+ maskInputOptions
1524
1671
  });
1525
- }
1526
- }
1527
- if (tagName === "img" && inlineImages) {
1528
- if (!canvasService) {
1529
- canvasService = doc.createElement("canvas");
1530
- canvasCtx = canvasService.getContext("2d");
1531
- }
1532
- const image = n2;
1533
- let overrideImage = null;
1534
- let calls = 0;
1535
- const imageSrc = (image.currentSrc || image.getAttribute("src") || "<unknown-src>") + "";
1536
- const imageHeight = image.naturalHeight;
1537
- const imageWidth = image.naturalWidth;
1538
- const inlineImageCleanup = () => {
1539
- overrideImage = null;
1540
- };
1541
- const recordInlineImage = () => {
1542
- calls++;
1543
- if (calls > 3) return;
1544
- (overrideImage != null ? overrideImage : image).removeEventListener("error", onImageLoadError);
1545
- try {
1546
- canvasService.width = imageWidth;
1547
- canvasService.height = imageHeight;
1548
- canvasCtx.drawImage(image, 0, 0);
1549
- attributes.rr_dataURL = canvasService.toDataURL(
1550
- dataURLOptions.type,
1551
- dataURLOptions.quality
1552
- );
1553
- } catch (err) {
1554
- if (image.crossOrigin !== "anonymous") {
1555
- if (shouldTryAnonymousFetchingOnCorsError$1()) {
1556
- overrideImage = new Image();
1557
- overrideImage.src = imageSrc;
1558
- overrideImage.crossOrigin = "anonymous";
1559
- overrideImage.height = imageHeight;
1560
- overrideImage.width = imageWidth;
1561
- if (overrideImage.complete && overrideImage.naturalWidth !== 0) {
1562
- recordInlineImage();
1563
- } else {
1564
- overrideImage.addEventListener("load", recordInlineImage, {
1565
- once: true
1566
- });
1567
- overrideImage.addEventListener("error", onImageLoadError, {
1568
- once: true
1569
- });
1570
- }
1571
- return;
1572
- }
1573
- } else {
1574
- if (isDebug$1())
1575
- console.warn(
1576
- `Cannot inline img src=${imageSrc}! Error: ${err}`
1577
- );
1578
- }
1672
+ break;
1673
+ case "dialog":
1674
+ if (n2.open) {
1675
+ attributes.rr_open_mode = n2.matches(
1676
+ "dialog:modal"
1677
+ ) ? "modal" : "non-modal";
1579
1678
  }
1580
- inlineImageCleanup();
1581
- };
1582
- const onImageLoadError = () => {
1583
- (overrideImage != null ? overrideImage : image).removeEventListener("load", recordInlineImage);
1584
- inlineImageCleanup();
1585
- };
1586
- if (image.complete && image.naturalWidth !== 0) recordInlineImage();
1587
- else {
1588
- image.addEventListener("load", recordInlineImage, { once: true });
1589
- image.addEventListener("error", onImageLoadError, { once: true });
1590
- }
1591
- }
1592
- if (tagName === "audio" || tagName === "video") {
1593
- const mediaAttributes = attributes;
1594
- mediaAttributes.rr_mediaState = n2.paused ? "paused" : "played";
1595
- mediaAttributes.rr_mediaCurrentTime = n2.currentTime;
1596
- mediaAttributes.rr_mediaPlaybackRate = n2.playbackRate;
1597
- mediaAttributes.rr_mediaMuted = n2.muted;
1598
- mediaAttributes.rr_mediaLoop = n2.loop;
1599
- mediaAttributes.rr_mediaVolume = n2.volume;
1679
+ break;
1680
+ case "canvas":
1681
+ if (recordCanvas) {
1682
+ attributes = serializeCanvas({
1683
+ attributes,
1684
+ n: n2,
1685
+ dataURLOptions,
1686
+ doc
1687
+ });
1688
+ }
1689
+ case "img":
1690
+ if (inlineImages) {
1691
+ attributes = serializeImageInline({
1692
+ attributes,
1693
+ n: n2,
1694
+ canvasService,
1695
+ canvasCtx,
1696
+ dataURLOptions,
1697
+ doc
1698
+ });
1699
+ }
1700
+ break;
1701
+ case "audio":
1702
+ case "video":
1703
+ attributes = serializeMediaElements({
1704
+ attributes,
1705
+ n: n2
1706
+ });
1707
+ break;
1600
1708
  }
1601
1709
  if (!newlyAddedElement) {
1602
1710
  if (n2.scrollLeft) {
@@ -1916,7 +2024,7 @@ function serializeNodeWithId(n2, options) {
1916
2024
  debugging.store[n2.nodeName] = [];
1917
2025
  }
1918
2026
  debugging.store[n2.nodeName].push(took);
1919
- if (debugging.index % 100 === 0) {
2027
+ if (debugging.index % 1e3 === 0) {
1920
2028
  debugging.index = 0;
1921
2029
  const avgs = Object.entries(debugging.store).map(([key, values]) => {
1922
2030
  return {
@@ -1924,7 +2032,7 @@ function serializeNodeWithId(n2, options) {
1924
2032
  avg: values.reduce((a2, b) => a2 + b, 0) / values.length
1925
2033
  };
1926
2034
  });
1927
- console.log("last 100 avgs", JSON.parse(JSON.stringify(avgs)));
2035
+ console.log("last 1000 avgs", JSON.parse(JSON.stringify(avgs)));
1928
2036
  debugging.store = {};
1929
2037
  }
1930
2038
  return serializedNode;