@lvce-editor/preview-sandbox-worker 1.1.0 → 1.3.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.
@@ -96,12 +96,6 @@ const array = value => {
96
96
  throw new AssertionError('expected value to be of type array');
97
97
  }
98
98
  };
99
- const string = value => {
100
- const type = getType(value);
101
- if (type !== String$1) {
102
- throw new AssertionError('expected value to be of type string');
103
- }
104
- };
105
99
 
106
100
  const isMessagePort = value => {
107
101
  return value && value instanceof MessagePort;
@@ -514,7 +508,7 @@ const IpcParentWithMessagePort$1 = {
514
508
 
515
509
  const Two$1 = '2.0';
516
510
  const callbacks$1 = Object.create(null);
517
- const get$3 = id => {
511
+ const get$2 = id => {
518
512
  return callbacks$1[id];
519
513
  };
520
514
  const remove$1 = id => {
@@ -663,7 +657,7 @@ const warn = (...args) => {
663
657
  console.warn(...args);
664
658
  };
665
659
  const resolve = (id, response) => {
666
- const fn = get$3(id);
660
+ const fn = get$2(id);
667
661
  if (!fn) {
668
662
  console.log(response);
669
663
  warn(`callback ${id} may already be disposed`);
@@ -713,7 +707,7 @@ const getErrorProperty = (error, prettyError) => {
713
707
  }
714
708
  };
715
709
  };
716
- const create$1$1 = (id, error) => {
710
+ const create$1 = (id, error) => {
717
711
  return {
718
712
  jsonrpc: Two$1,
719
713
  id,
@@ -724,9 +718,9 @@ const getErrorResponse = (id, error, preparePrettyError, logError) => {
724
718
  const prettyError = preparePrettyError(error);
725
719
  logError(error, prettyError);
726
720
  const errorProperty = getErrorProperty(error, prettyError);
727
- return create$1$1(id, errorProperty);
721
+ return create$1(id, errorProperty);
728
722
  };
729
- const create$4 = (message, result) => {
723
+ const create$3 = (message, result) => {
730
724
  return {
731
725
  jsonrpc: Two$1,
732
726
  id: message.id,
@@ -735,7 +729,7 @@ const create$4 = (message, result) => {
735
729
  };
736
730
  const getSuccessResponse = (message, result) => {
737
731
  const resultProperty = result ?? null;
738
- return create$4(message, resultProperty);
732
+ return create$3(message, resultProperty);
739
733
  };
740
734
  const getErrorResponseSimple = (id, error) => {
741
735
  return {
@@ -963,53 +957,6 @@ const listen$1 = async (module, options) => {
963
957
  const ipc = module.wrap(rawIpc);
964
958
  return ipc;
965
959
  };
966
-
967
- /* eslint-disable @typescript-eslint/no-misused-promises */
968
-
969
- const createSharedLazyRpc = factory => {
970
- let rpcPromise;
971
- const getOrCreate = () => {
972
- if (!rpcPromise) {
973
- rpcPromise = factory();
974
- }
975
- return rpcPromise;
976
- };
977
- return {
978
- async dispose() {
979
- const rpc = await getOrCreate();
980
- await rpc.dispose();
981
- },
982
- async invoke(method, ...params) {
983
- const rpc = await getOrCreate();
984
- return rpc.invoke(method, ...params);
985
- },
986
- async invokeAndTransfer(method, ...params) {
987
- const rpc = await getOrCreate();
988
- return rpc.invokeAndTransfer(method, ...params);
989
- },
990
- async send(method, ...params) {
991
- const rpc = await getOrCreate();
992
- rpc.send(method, ...params);
993
- }
994
- };
995
- };
996
- const create$j = async ({
997
- commandMap,
998
- isMessagePortOpen,
999
- send
1000
- }) => {
1001
- return createSharedLazyRpc(() => {
1002
- return create$3({
1003
- commandMap,
1004
- isMessagePortOpen,
1005
- send
1006
- });
1007
- });
1008
- };
1009
- const LazyTransferMessagePortRpcParent = {
1010
- __proto__: null,
1011
- create: create$j
1012
- };
1013
960
  const create$5 = async ({
1014
961
  commandMap,
1015
962
  isMessagePortOpen = true,
@@ -1031,23 +978,7 @@ const PlainMessagePortRpc = {
1031
978
  __proto__: null,
1032
979
  create: create$5
1033
980
  };
1034
- const create$3 = async ({
1035
- commandMap,
1036
- isMessagePortOpen,
1037
- send
1038
- }) => {
1039
- const {
1040
- port1,
1041
- port2
1042
- } = new MessageChannel();
1043
- await send(port1);
1044
- return create$5({
1045
- commandMap,
1046
- isMessagePortOpen,
1047
- messagePort: port2
1048
- });
1049
- };
1050
- const create$2$1 = async ({
981
+ const create$2 = async ({
1051
982
  commandMap
1052
983
  }) => {
1053
984
  // TODO create a commandMap per rpc instance
@@ -1059,7 +990,7 @@ const create$2$1 = async ({
1059
990
  };
1060
991
  const WebWorkerRpcClient = {
1061
992
  __proto__: null,
1062
- create: create$2$1
993
+ create: create$2
1063
994
  };
1064
995
  const createMockRpc = ({
1065
996
  commandMap
@@ -1089,7 +1020,7 @@ const Span$1 = 8;
1089
1020
  const Table$1 = 9;
1090
1021
  const TBody$1 = 10;
1091
1022
  const Td$1 = 11;
1092
- const Text$2 = 12;
1023
+ const Text = 12;
1093
1024
  const Th$1 = 13;
1094
1025
  const THead$1 = 14;
1095
1026
  const Tr$1 = 15;
@@ -1136,17 +1067,13 @@ const Html = 73;
1136
1067
  const Canvas$1 = 77;
1137
1068
  const Reference = 100;
1138
1069
 
1139
- const EditorWorker = 99;
1140
1070
  const RendererWorker = 1;
1141
1071
 
1142
- const SetDom2 = 'Viewlet.setDom2';
1143
- const SetPatches = 'Viewlet.setPatches';
1144
-
1145
1072
  const rpcs = Object.create(null);
1146
- const set$5 = (id, rpc) => {
1073
+ const set$4 = (id, rpc) => {
1147
1074
  rpcs[id] = rpc;
1148
1075
  };
1149
- const get$2 = id => {
1076
+ const get$1 = id => {
1150
1077
  return rpcs[id];
1151
1078
  };
1152
1079
  const remove = id => {
@@ -1154,21 +1081,21 @@ const remove = id => {
1154
1081
  };
1155
1082
 
1156
1083
  /* eslint-disable @typescript-eslint/explicit-function-return-type */
1157
- const create$2 = rpcId => {
1084
+ const create = rpcId => {
1158
1085
  return {
1159
1086
  async dispose() {
1160
- const rpc = get$2(rpcId);
1087
+ const rpc = get$1(rpcId);
1161
1088
  await rpc.dispose();
1162
1089
  },
1163
1090
  // @ts-ignore
1164
1091
  invoke(method, ...params) {
1165
- const rpc = get$2(rpcId);
1092
+ const rpc = get$1(rpcId);
1166
1093
  // @ts-ignore
1167
1094
  return rpc.invoke(method, ...params);
1168
1095
  },
1169
1096
  // @ts-ignore
1170
1097
  invokeAndTransfer(method, ...params) {
1171
- const rpc = get$2(rpcId);
1098
+ const rpc = get$1(rpcId);
1172
1099
  // @ts-ignore
1173
1100
  return rpc.invokeAndTransfer(method, ...params);
1174
1101
  },
@@ -1176,7 +1103,7 @@ const create$2 = rpcId => {
1176
1103
  const mockRpc = createMockRpc({
1177
1104
  commandMap
1178
1105
  });
1179
- set$5(rpcId, mockRpc);
1106
+ set$4(rpcId, mockRpc);
1180
1107
  // @ts-ignore
1181
1108
  mockRpc[Symbol.dispose] = () => {
1182
1109
  remove(rpcId);
@@ -1185,202 +1112,27 @@ const create$2 = rpcId => {
1185
1112
  return mockRpc;
1186
1113
  },
1187
1114
  set(rpc) {
1188
- set$5(rpcId, rpc);
1115
+ set$4(rpcId, rpc);
1189
1116
  }
1190
1117
  };
1191
1118
  };
1192
1119
 
1193
1120
  const {
1194
1121
  invoke: invoke$1,
1195
- set: set$4
1196
- } = create$2(EditorWorker);
1122
+ set: set$3
1123
+ } = create(3211);
1197
1124
 
1198
1125
  const {
1199
1126
  invoke,
1200
- invokeAndTransfer,
1201
- set: set$3
1202
- } = create$2(RendererWorker);
1203
- const sendMessagePortToEditorWorker = async (port, rpcId) => {
1204
- const command = 'HandleMessagePort.handleMessagePort';
1205
- await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToEditorWorker', port, command, rpcId);
1206
- };
1207
- const readFile = async uri => {
1208
- return invoke('FileSystem.readFile', uri);
1209
- };
1127
+ set: set$2
1128
+ } = create(RendererWorker);
1210
1129
 
1211
- const toCommandId = key => {
1212
- const dotIndex = key.indexOf('.');
1213
- return key.slice(dotIndex + 1);
1214
- };
1215
- const create$1 = () => {
1216
- const states = Object.create(null);
1217
- const commandMapRef = {};
1218
- return {
1219
- clear() {
1220
- for (const key of Object.keys(states)) {
1221
- delete states[key];
1222
- }
1223
- },
1224
- diff(uid, modules, numbers) {
1225
- const {
1226
- newState,
1227
- oldState
1228
- } = states[uid];
1229
- const diffResult = [];
1230
- for (let i = 0; i < modules.length; i++) {
1231
- const fn = modules[i];
1232
- if (!fn(oldState, newState)) {
1233
- diffResult.push(numbers[i]);
1234
- }
1235
- }
1236
- return diffResult;
1237
- },
1238
- dispose(uid) {
1239
- delete states[uid];
1240
- },
1241
- get(uid) {
1242
- return states[uid];
1243
- },
1244
- getCommandIds() {
1245
- const keys = Object.keys(commandMapRef);
1246
- const ids = keys.map(toCommandId);
1247
- return ids;
1248
- },
1249
- getKeys() {
1250
- return Object.keys(states).map(key => {
1251
- return Number.parseInt(key);
1252
- });
1253
- },
1254
- registerCommands(commandMap) {
1255
- Object.assign(commandMapRef, commandMap);
1256
- },
1257
- set(uid, oldState, newState) {
1258
- states[uid] = {
1259
- newState,
1260
- oldState
1261
- };
1262
- },
1263
- wrapCommand(fn) {
1264
- const wrapped = async (uid, ...args) => {
1265
- const {
1266
- newState,
1267
- oldState
1268
- } = states[uid];
1269
- const newerState = await fn(newState, ...args);
1270
- if (oldState === newerState || newState === newerState) {
1271
- return;
1272
- }
1273
- const latestOld = states[uid];
1274
- const latestNew = {
1275
- ...latestOld.newState,
1276
- ...newerState
1277
- };
1278
- states[uid] = {
1279
- newState: latestNew,
1280
- oldState: latestOld.oldState
1281
- };
1282
- };
1283
- return wrapped;
1284
- },
1285
- wrapGetter(fn) {
1286
- const wrapped = (uid, ...args) => {
1287
- const {
1288
- newState
1289
- } = states[uid];
1290
- return fn(newState, ...args);
1291
- };
1292
- return wrapped;
1293
- }
1294
- };
1295
- };
1296
1130
  const terminate = () => {
1297
1131
  globalThis.close();
1298
1132
  };
1299
1133
 
1300
- const createSandboxRpc = async () => {
1301
- const sandboxRpc = await LazyTransferMessagePortRpcParent.create({
1302
- commandMap: {},
1303
- send: async port => await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToPreviewSandBoxWorker', port, 'SandBox.handleMessagePort')
1304
- });
1305
- return sandboxRpc;
1306
- };
1307
-
1308
- const {
1309
- get: get$1,
1310
- registerCommands,
1311
- set: set$2,
1312
- wrapCommand} = create$1();
1313
-
1314
- const create = async (uid, uri, x, y, width, height, platform, assetDir) => {
1315
- const sandboxRpc = await createSandboxRpc();
1316
- const state = {
1317
- assetDir,
1318
- content: '',
1319
- css: [],
1320
- errorCount: 0,
1321
- errorMessage: '',
1322
- height,
1323
- initial: true,
1324
- parsedDom: [],
1325
- parsedNodesChildNodeCount: 0,
1326
- platform,
1327
- sandboxRpc,
1328
- scripts: [],
1329
- uid,
1330
- uri,
1331
- useSandboxWorker: false,
1332
- warningCount: 0,
1333
- width,
1334
- x,
1335
- y
1336
- };
1337
- set$2(uid, state, state);
1338
- };
1339
-
1340
- const iEqual = (oldState, newState) => {
1341
- if (oldState.css.length !== newState.css.length) {
1342
- return false;
1343
- }
1344
- for (let i = 0; i < oldState.css.length; i++) {
1345
- if (oldState.css[i] !== newState.css[i]) {
1346
- return false;
1347
- }
1348
- }
1349
- return true;
1350
- };
1351
-
1352
- const isEqual = (oldState, newState) => {
1353
- return oldState.warningCount === newState.warningCount && oldState.initial === newState.initial && oldState.content === newState.content && oldState.parsedDom === newState.parsedDom && oldState.parsedNodesChildNodeCount === newState.parsedNodesChildNodeCount && oldState.css === newState.css && oldState.scripts === newState.scripts;
1354
- };
1355
-
1356
- const RenderItems = 4;
1357
- const RenderCss = 10;
1358
- const RenderIncremental = 11;
1359
-
1360
- const modules = [isEqual, iEqual];
1361
- const numbers = [RenderIncremental, RenderCss];
1362
-
1363
- const diff = (oldState, newState) => {
1364
- const diffResult = [];
1365
- for (let i = 0; i < modules.length; i++) {
1366
- const fn = modules[i];
1367
- if (!fn(oldState, newState)) {
1368
- diffResult.push(numbers[i]);
1369
- }
1370
- }
1371
- return diffResult;
1372
- };
1373
-
1374
- const diff2 = uid => {
1375
- const {
1376
- newState,
1377
- oldState
1378
- } = get$1(uid);
1379
- const result = diff(oldState, newState);
1380
- return result;
1381
- };
1382
-
1383
1134
  /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
1135
+
1384
1136
  const callBacks = Object.create(null);
1385
1137
  let id = 0;
1386
1138
  const registerCallback = () => {
@@ -1404,12 +1156,13 @@ const executeCallback = (id, ...args) => {
1404
1156
  console.warn(`[preview-sandbox-worker] No callback found for id ${id}`);
1405
1157
  }
1406
1158
  };
1407
- const getOffscreenCanvas = async (width, height) => {
1159
+ const getOffscreenCanvas = async (uid, width, height) => {
1160
+ // TODO ask preview worker
1408
1161
  const {
1409
1162
  id,
1410
1163
  promise
1411
1164
  } = registerCallback();
1412
- await invoke('OffscreenCanvas.createForPreview', id, width, height);
1165
+ await invoke$1('Preview.createOffscreenCanvas', uid, id, width, height);
1413
1166
  const [offscreenCanvas, canvasId] = await promise;
1414
1167
  return {
1415
1168
  canvasId,
@@ -1417,61 +1170,6 @@ const getOffscreenCanvas = async (width, height) => {
1417
1170
  };
1418
1171
  };
1419
1172
 
1420
- const dispatchEvent = (element, event) => {
1421
- element.dispatchEvent(event);
1422
-
1423
- // Also invoke direct on* handler if set (e.g. element.onclick = function(){})
1424
- const handlerName = `on${event.type}`;
1425
- const handler = element[handlerName];
1426
- if (typeof handler === 'function') {
1427
- handler.call(element, event);
1428
- } else if (handler === null || handler === undefined) {
1429
- if (!element.getAttribute) {
1430
- return;
1431
- }
1432
- // Check if there's an inline HTML attribute that wasn't converted to a property
1433
- const attrValue = element.getAttribute(handlerName);
1434
- if (attrValue && typeof attrValue === 'string' && element.ownerDocument && element.ownerDocument.defaultView) {
1435
- const window = element.ownerDocument.defaultView;
1436
- // Handle inline event handlers like onclick="someFunction(2)"
1437
- // Evaluate in the context of the window so functions are in scope
1438
- // eslint-disable-next-line @typescript-eslint/no-implied-eval
1439
- const fn = new Function('event', `with(this) { ${attrValue} }`);
1440
- fn.call(window, event);
1441
- }
1442
- }
1443
- };
1444
-
1445
- const dispatchClickEvent = (element, window) => {
1446
- const clickEvent = new window.MouseEvent('click', {
1447
- bubbles: true
1448
- });
1449
- dispatchEvent(element, clickEvent);
1450
- };
1451
-
1452
- const getParsedNodesChildNodeCount = parsedDom => {
1453
- array(parsedDom);
1454
- const rootCountFromParse = parsedDom.rootChildCount;
1455
- if (typeof rootCountFromParse === 'number') {
1456
- return rootCountFromParse;
1457
- }
1458
- let rootChildCount = 0;
1459
- let i = 0;
1460
- while (i < parsedDom.length) {
1461
- rootChildCount++;
1462
-
1463
- // skip the entire subtree of the current node
1464
- let toSkip = parsedDom[i].childCount;
1465
- i++;
1466
- while (toSkip > 0 && i < parsedDom.length) {
1467
- toSkip -= 1;
1468
- toSkip += parsedDom[i].childCount;
1469
- i++;
1470
- }
1471
- }
1472
- return rootChildCount;
1473
- };
1474
-
1475
1173
  /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
1476
1174
 
1477
1175
  const states$1 = new Map();
@@ -1486,298 +1184,10 @@ const text = data => {
1486
1184
  return {
1487
1185
  childCount: 0,
1488
1186
  text: data,
1489
- type: Text$2
1490
- };
1491
- };
1492
-
1493
- const SetText = 1;
1494
- const Replace = 2;
1495
- const SetAttribute = 3;
1496
- const RemoveAttribute = 4;
1497
- const Add = 6;
1498
- const NavigateChild = 7;
1499
- const NavigateParent = 8;
1500
- const RemoveChild = 9;
1501
- const NavigateSibling = 10;
1502
- const SetReferenceNodeUid = 11;
1503
-
1504
- const isKey = key => {
1505
- return key !== 'type' && key !== 'childCount';
1506
- };
1507
-
1508
- const getKeys = node => {
1509
- const keys = Object.keys(node).filter(isKey);
1510
- return keys;
1511
- };
1512
-
1513
- const arrayToTree = nodes => {
1514
- const result = [];
1515
- let i = 0;
1516
- while (i < nodes.length) {
1517
- const node = nodes[i];
1518
- const {
1519
- children,
1520
- nodesConsumed
1521
- } = getChildrenWithCount(nodes, i + 1, node.childCount || 0);
1522
- result.push({
1523
- node,
1524
- children
1525
- });
1526
- i += 1 + nodesConsumed;
1527
- }
1528
- return result;
1529
- };
1530
- const getChildrenWithCount = (nodes, startIndex, childCount) => {
1531
- if (childCount === 0) {
1532
- return {
1533
- children: [],
1534
- nodesConsumed: 0
1535
- };
1536
- }
1537
- const children = [];
1538
- let i = startIndex;
1539
- let remaining = childCount;
1540
- let totalConsumed = 0;
1541
- while (remaining > 0 && i < nodes.length) {
1542
- const node = nodes[i];
1543
- const nodeChildCount = node.childCount || 0;
1544
- const {
1545
- children: nodeChildren,
1546
- nodesConsumed
1547
- } = getChildrenWithCount(nodes, i + 1, nodeChildCount);
1548
- children.push({
1549
- node,
1550
- children: nodeChildren
1551
- });
1552
- const nodeSize = 1 + nodesConsumed;
1553
- i += nodeSize;
1554
- totalConsumed += nodeSize;
1555
- remaining--;
1556
- }
1557
- return {
1558
- children,
1559
- nodesConsumed: totalConsumed
1187
+ type: Text
1560
1188
  };
1561
1189
  };
1562
1190
 
1563
- const compareNodes = (oldNode, newNode) => {
1564
- const patches = [];
1565
- // Check if node type changed - return null to signal incompatible nodes
1566
- // (caller should handle this with a Replace operation)
1567
- if (oldNode.type !== newNode.type) {
1568
- return null;
1569
- }
1570
- // Handle reference nodes - special handling for uid changes
1571
- if (oldNode.type === Reference) {
1572
- if (oldNode.uid !== newNode.uid) {
1573
- patches.push({
1574
- type: SetReferenceNodeUid,
1575
- uid: newNode.uid
1576
- });
1577
- }
1578
- return patches;
1579
- }
1580
- // Handle text nodes
1581
- if (oldNode.type === Text$2 && newNode.type === Text$2) {
1582
- if (oldNode.text !== newNode.text) {
1583
- patches.push({
1584
- type: SetText,
1585
- value: newNode.text
1586
- });
1587
- }
1588
- return patches;
1589
- }
1590
- // Compare attributes
1591
- const oldKeys = getKeys(oldNode);
1592
- const newKeys = getKeys(newNode);
1593
- // Check for attribute changes
1594
- for (const key of newKeys) {
1595
- if (oldNode[key] !== newNode[key]) {
1596
- patches.push({
1597
- type: SetAttribute,
1598
- key,
1599
- value: newNode[key]
1600
- });
1601
- }
1602
- }
1603
- // Check for removed attributes
1604
- for (const key of oldKeys) {
1605
- if (!(key in newNode)) {
1606
- patches.push({
1607
- type: RemoveAttribute,
1608
- key
1609
- });
1610
- }
1611
- }
1612
- return patches;
1613
- };
1614
-
1615
- const treeToArray = node => {
1616
- const result = [node.node];
1617
- for (const child of node.children) {
1618
- result.push(...treeToArray(child));
1619
- }
1620
- return result;
1621
- };
1622
-
1623
- const diffChildren = (oldChildren, newChildren, patches) => {
1624
- const maxLength = Math.max(oldChildren.length, newChildren.length);
1625
- // Track where we are: -1 means at parent, >= 0 means at child index
1626
- let currentChildIndex = -1;
1627
- // Collect indices of children to remove (we'll add these patches at the end in reverse order)
1628
- const indicesToRemove = [];
1629
- for (let i = 0; i < maxLength; i++) {
1630
- const oldNode = oldChildren[i];
1631
- const newNode = newChildren[i];
1632
- if (!oldNode && !newNode) {
1633
- continue;
1634
- }
1635
- if (!oldNode) {
1636
- // Add new node - we should be at the parent
1637
- if (currentChildIndex >= 0) {
1638
- // Navigate back to parent
1639
- patches.push({
1640
- type: NavigateParent
1641
- });
1642
- currentChildIndex = -1;
1643
- }
1644
- // Flatten the entire subtree so renderInternal can handle it
1645
- const flatNodes = treeToArray(newNode);
1646
- patches.push({
1647
- type: Add,
1648
- nodes: flatNodes
1649
- });
1650
- } else if (newNode) {
1651
- // Compare nodes to see if we need any patches
1652
- const nodePatches = compareNodes(oldNode.node, newNode.node);
1653
- // If nodePatches is null, the node types are incompatible - need to replace
1654
- if (nodePatches === null) {
1655
- // Navigate to this child
1656
- if (currentChildIndex === -1) {
1657
- patches.push({
1658
- type: NavigateChild,
1659
- index: i
1660
- });
1661
- currentChildIndex = i;
1662
- } else if (currentChildIndex !== i) {
1663
- patches.push({
1664
- type: NavigateSibling,
1665
- index: i
1666
- });
1667
- currentChildIndex = i;
1668
- }
1669
- // Replace the entire subtree
1670
- const flatNodes = treeToArray(newNode);
1671
- patches.push({
1672
- type: Replace,
1673
- nodes: flatNodes
1674
- });
1675
- // After replace, we're at the new element (same position)
1676
- continue;
1677
- }
1678
- // Check if we need to recurse into children
1679
- const hasChildrenToCompare = oldNode.children.length > 0 || newNode.children.length > 0;
1680
- // Only navigate to this element if we need to do something
1681
- if (nodePatches.length > 0 || hasChildrenToCompare) {
1682
- // Navigate to this child if not already there
1683
- if (currentChildIndex === -1) {
1684
- patches.push({
1685
- type: NavigateChild,
1686
- index: i
1687
- });
1688
- currentChildIndex = i;
1689
- } else if (currentChildIndex !== i) {
1690
- patches.push({
1691
- type: NavigateSibling,
1692
- index: i
1693
- });
1694
- currentChildIndex = i;
1695
- }
1696
- // Apply node patches (these apply to the current element, not children)
1697
- if (nodePatches.length > 0) {
1698
- patches.push(...nodePatches);
1699
- }
1700
- // Compare children recursively
1701
- if (hasChildrenToCompare) {
1702
- diffChildren(oldNode.children, newNode.children, patches);
1703
- }
1704
- }
1705
- } else {
1706
- // Remove old node - collect the index for later removal
1707
- indicesToRemove.push(i);
1708
- }
1709
- }
1710
- // Navigate back to parent if we ended at a child
1711
- if (currentChildIndex >= 0) {
1712
- patches.push({
1713
- type: NavigateParent
1714
- });
1715
- currentChildIndex = -1;
1716
- }
1717
- // Add remove patches in reverse order (highest index first)
1718
- // This ensures indices remain valid as we remove
1719
- for (let j = indicesToRemove.length - 1; j >= 0; j--) {
1720
- patches.push({
1721
- type: RemoveChild,
1722
- index: indicesToRemove[j]
1723
- });
1724
- }
1725
- };
1726
- const diffTrees = (oldTree, newTree, patches, path) => {
1727
- // At the root level (path.length === 0), we're already AT the element
1728
- // So we compare the root node directly, then compare its children
1729
- if (path.length === 0 && oldTree.length === 1 && newTree.length === 1) {
1730
- const oldNode = oldTree[0];
1731
- const newNode = newTree[0];
1732
- // Compare root nodes
1733
- const nodePatches = compareNodes(oldNode.node, newNode.node);
1734
- // If nodePatches is null, the root node types are incompatible - need to replace
1735
- if (nodePatches === null) {
1736
- const flatNodes = treeToArray(newNode);
1737
- patches.push({
1738
- type: Replace,
1739
- nodes: flatNodes
1740
- });
1741
- return;
1742
- }
1743
- if (nodePatches.length > 0) {
1744
- patches.push(...nodePatches);
1745
- }
1746
- // Compare children
1747
- if (oldNode.children.length > 0 || newNode.children.length > 0) {
1748
- diffChildren(oldNode.children, newNode.children, patches);
1749
- }
1750
- } else {
1751
- // Non-root level or multiple root elements - use the regular comparison
1752
- diffChildren(oldTree, newTree, patches);
1753
- }
1754
- };
1755
-
1756
- const removeTrailingNavigationPatches = patches => {
1757
- // Find the last non-navigation patch
1758
- let lastNonNavigationIndex = -1;
1759
- for (let i = patches.length - 1; i >= 0; i--) {
1760
- const patch = patches[i];
1761
- if (patch.type !== NavigateChild && patch.type !== NavigateParent && patch.type !== NavigateSibling) {
1762
- lastNonNavigationIndex = i;
1763
- break;
1764
- }
1765
- }
1766
- // Return patches up to and including the last non-navigation patch
1767
- return lastNonNavigationIndex === -1 ? [] : patches.slice(0, lastNonNavigationIndex + 1);
1768
- };
1769
-
1770
- const diffTree = (oldNodes, newNodes) => {
1771
- // Step 1: Convert flat arrays to tree structures
1772
- const oldTree = arrayToTree(oldNodes);
1773
- const newTree = arrayToTree(newNodes);
1774
- // Step 3: Compare the trees
1775
- const patches = [];
1776
- diffTrees(oldTree, newTree, patches, []);
1777
- // Remove trailing navigation patches since they serve no purpose
1778
- return removeTrailingNavigationPatches(patches);
1779
- };
1780
-
1781
1191
  const Div = 'div';
1782
1192
  const H1 = 'h1';
1783
1193
  const H2 = 'h2';
@@ -1985,7 +1395,7 @@ const isDefaultAllowedAttribute = (attributeName, defaultAllowedAttributes) => {
1985
1395
  const TAGS_TO_SKIP = new Set(['script', 'meta', 'title']);
1986
1396
 
1987
1397
  // Tags to skip but process children
1988
- const TAGS_TO_SKIP_TAG_ONLY$1 = new Set(['html', 'body', 'head']);
1398
+ const TAGS_TO_SKIP_TAG_ONLY = new Set(['html', 'body', 'head']);
1989
1399
 
1990
1400
  // Tags where we extract content as CSS
1991
1401
  const CSS_TAGS = new Set(['style']);
@@ -2026,7 +1436,7 @@ const serializeNode = (node, dom, css, context) => {
2026
1436
  }
2027
1437
 
2028
1438
  // For html/body tags, serialize children only
2029
- if (TAGS_TO_SKIP_TAG_ONLY$1.has(tagName)) {
1439
+ if (TAGS_TO_SKIP_TAG_ONLY.has(tagName)) {
2030
1440
  let childCount = 0;
2031
1441
  const {
2032
1442
  childNodes
@@ -2136,62 +1546,261 @@ const serialize = (document, elementMap) => {
2136
1546
  };
2137
1547
  };
2138
1548
 
2139
- const handleClickSandbox = async (state, hdId) => {
2140
- const {
2141
- sandboxRpc,
2142
- uid
2143
- } = state;
2144
- await sandboxRpc.invoke('SandBox.handleClick', uid, hdId);
2145
- const serialized = await sandboxRpc.invoke('SandBox.getSerializedDom', uid);
2146
- const parsedDom = serialized.dom;
1549
+ const getSerializedDom = uid => {
1550
+ const item = get(uid);
1551
+ if (!item) {
1552
+ throw new Error(`No HappyDom instance found for uid ${uid}`);
1553
+ }
2147
1554
  const {
2148
- css
2149
- } = serialized;
2150
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
2151
- return {
2152
- ...state,
2153
- css,
2154
- parsedDom,
2155
- parsedNodesChildNodeCount
2156
- };
1555
+ document,
1556
+ elementMap
1557
+ } = item;
1558
+ const serialized = serialize(document, elementMap);
1559
+ return serialized;
1560
+ };
1561
+
1562
+ const dispatchEvent = (element, event) => {
1563
+ element.dispatchEvent(event);
1564
+
1565
+ // Also invoke direct on* handler if set (e.g. element.onclick = function(){})
1566
+ const handlerName = `on${event.type}`;
1567
+ const handler = element[handlerName];
1568
+ if (typeof handler === 'function') {
1569
+ handler.call(element, event);
1570
+ } else if (handler === null || handler === undefined) {
1571
+ if (!element.getAttribute) {
1572
+ return;
1573
+ }
1574
+ // Check if there's an inline HTML attribute that wasn't converted to a property
1575
+ const attrValue = element.getAttribute(handlerName);
1576
+ if (attrValue && typeof attrValue === 'string' && element.ownerDocument && element.ownerDocument.defaultView) {
1577
+ const window = element.ownerDocument.defaultView;
1578
+ // Handle inline event handlers like onclick="someFunction(2)"
1579
+ // Evaluate in the context of the window so functions are in scope
1580
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval
1581
+ const fn = new Function('event', `with(this) { ${attrValue} }`);
1582
+ fn.call(window, event);
1583
+ }
1584
+ }
1585
+ };
1586
+
1587
+ const dispatchClickEvent = (element, window) => {
1588
+ const clickEvent = new window.MouseEvent('click', {
1589
+ bubbles: true
1590
+ });
1591
+ dispatchEvent(element, clickEvent);
2157
1592
  };
2158
- const handleClickLocal = (state, hdId) => {
2159
- const happyDomInstance = get(state.uid);
1593
+
1594
+ const handleClickLocal = (uid, hdId) => {
1595
+ const happyDomInstance = get(uid);
2160
1596
  if (!happyDomInstance) {
2161
- return state;
1597
+ return;
2162
1598
  }
2163
1599
  const element = happyDomInstance.elementMap.get(hdId);
2164
1600
  if (!element) {
2165
- return state;
1601
+ return;
2166
1602
  }
2167
1603
  dispatchClickEvent(element, happyDomInstance.window);
2168
1604
  const elementMap = new Map();
2169
- const serialized = serialize(happyDomInstance.document, elementMap);
2170
- set$1(state.uid, {
1605
+ set$1(uid, {
2171
1606
  document: happyDomInstance.document,
2172
1607
  elementMap,
2173
1608
  window: happyDomInstance.window
2174
1609
  });
2175
- const parsedDom = serialized.dom;
2176
- const {
2177
- css
2178
- } = serialized;
2179
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
2180
- return {
2181
- ...state,
2182
- css,
2183
- parsedDom,
2184
- parsedNodesChildNodeCount
2185
- };
2186
1610
  };
2187
- const handleClick = (state, hdId) => {
2188
- if (!hdId) {
2189
- return state;
1611
+ const handleClick = (uid, hdId) => {
1612
+ return handleClickLocal(uid, hdId);
1613
+ };
1614
+
1615
+ const dispatchInputEvent = (element, window) => {
1616
+ const inputEvent = new window.Event('input', {
1617
+ bubbles: true
1618
+ });
1619
+ dispatchEvent(element, inputEvent);
1620
+ };
1621
+
1622
+ const handleInputLocal = (uid, hdId, value) => {
1623
+ const happyDomInstance = get(uid);
1624
+ if (!happyDomInstance) {
1625
+ return;
1626
+ }
1627
+ const element = happyDomInstance.elementMap.get(hdId);
1628
+ if (!element) {
1629
+ return;
1630
+ }
1631
+ element.value = value;
1632
+ dispatchInputEvent(element, happyDomInstance.window);
1633
+ const elementMap = new Map();
1634
+ set$1(uid, {
1635
+ document: happyDomInstance.document,
1636
+ elementMap,
1637
+ window: happyDomInstance.window
1638
+ });
1639
+ };
1640
+ const handleInput = (uid, hdId, value) => {
1641
+ return handleInputLocal(uid, hdId, value);
1642
+ };
1643
+
1644
+ const dispatchKeydownEvent = (element, window, key, code) => {
1645
+ const keydownEvent = new window.KeyboardEvent('keydown', {
1646
+ bubbles: true,
1647
+ code,
1648
+ key
1649
+ });
1650
+ dispatchEvent(element, keydownEvent);
1651
+ };
1652
+
1653
+ const handleKeydownLocal = (uid, hdId, key, code) => {
1654
+ const happyDomInstance = get(uid);
1655
+ if (!happyDomInstance) {
1656
+ return;
1657
+ }
1658
+ const element = hdId ? happyDomInstance.elementMap.get(hdId) : happyDomInstance.document;
1659
+ if (!element) {
1660
+ return;
1661
+ }
1662
+ dispatchKeydownEvent(element, happyDomInstance.window, key, code);
1663
+ const elementMap = new Map();
1664
+ set$1(uid, {
1665
+ document: happyDomInstance.document,
1666
+ elementMap,
1667
+ window: happyDomInstance.window
1668
+ });
1669
+ };
1670
+ const handleKeydown = (uid, hdId, key, code) => {
1671
+ return handleKeydownLocal(uid, hdId, key, code);
1672
+ };
1673
+
1674
+ const dispatchKeyupEvent = (element, window, key, code) => {
1675
+ const keyupEvent = new window.KeyboardEvent('keyup', {
1676
+ bubbles: true,
1677
+ code,
1678
+ key
1679
+ });
1680
+ dispatchEvent(element, keyupEvent);
1681
+ };
1682
+
1683
+ const handleKeyupLocal = (uid, hdId, key, code) => {
1684
+ const happyDomInstance = get(uid);
1685
+ if (!happyDomInstance) {
1686
+ return;
1687
+ }
1688
+ const element = hdId ? happyDomInstance.elementMap.get(hdId) : happyDomInstance.document;
1689
+ if (!element) {
1690
+ return;
1691
+ }
1692
+ dispatchKeyupEvent(element, happyDomInstance.window, key, code);
1693
+ const elementMap = new Map();
1694
+ set$1(uid, {
1695
+ document: happyDomInstance.document,
1696
+ elementMap,
1697
+ window: happyDomInstance.window
1698
+ });
1699
+ };
1700
+ const handleKeyup = (uid, hdId, key, code) => {
1701
+ return handleKeyupLocal(uid, hdId, key, code);
1702
+ };
1703
+
1704
+ const handleMessagePort = async port => {
1705
+ const rpc = await PlainMessagePortRpc.create({
1706
+ commandMap: {},
1707
+ messagePort: port
1708
+ });
1709
+ set$3(rpc);
1710
+ };
1711
+
1712
+ const dispatchMousedownEvent = (element, window, clientX = 0, clientY = 0) => {
1713
+ const mousedownEvent = new window.MouseEvent('mousedown', {
1714
+ bubbles: true,
1715
+ clientX,
1716
+ clientY
1717
+ });
1718
+ dispatchEvent(element, mousedownEvent);
1719
+ };
1720
+
1721
+ const handleMousedownLocal = (uid, hdId, clientX, clientY, x, y) => {
1722
+ const happyDomInstance = get(uid);
1723
+ if (!happyDomInstance) {
1724
+ return;
1725
+ }
1726
+ const element = happyDomInstance.elementMap.get(hdId);
1727
+ if (!element) {
1728
+ return;
1729
+ }
1730
+ const adjustedClientX = clientX - x;
1731
+ const adjustedClientY = clientY - y;
1732
+ dispatchMousedownEvent(element, happyDomInstance.window, adjustedClientX, adjustedClientY);
1733
+ const elementMap = new Map();
1734
+ set$1(uid, {
1735
+ document: happyDomInstance.document,
1736
+ elementMap,
1737
+ window: happyDomInstance.window
1738
+ });
1739
+ };
1740
+ const handleMousedown = (uid, hdId, clientX, clientY, x, y) => {
1741
+ return handleMousedownLocal(uid, hdId, clientX, clientY, x, y);
1742
+ };
1743
+
1744
+ const dispatchMousemoveEvent = (element, window, clientX = 0, clientY = 0) => {
1745
+ const mousemoveEvent = new window.MouseEvent('mousemove', {
1746
+ bubbles: true,
1747
+ clientX,
1748
+ clientY
1749
+ });
1750
+ dispatchEvent(element, mousemoveEvent);
1751
+ };
1752
+
1753
+ const handleMousemoveLocal = (uid, hdId, clientX, clientY, x, y) => {
1754
+ const happyDomInstance = get(uid);
1755
+ if (!happyDomInstance) {
1756
+ return;
1757
+ }
1758
+ const element = happyDomInstance.elementMap.get(hdId);
1759
+ if (!element) {
1760
+ return;
1761
+ }
1762
+ const adjustedClientX = clientX - x;
1763
+ const adjustedClientY = clientY - y;
1764
+ dispatchMousemoveEvent(element, happyDomInstance.window, adjustedClientX, adjustedClientY);
1765
+ const elementMap = new Map();
1766
+ set$1(uid, {
1767
+ document: happyDomInstance.document,
1768
+ elementMap,
1769
+ window: happyDomInstance.window
1770
+ });
1771
+ };
1772
+ const handleMousemove = (uid, hdId, clientX, clientY, x, y) => {
1773
+ return handleMousemoveLocal(uid, hdId, clientX, clientY, x, y);
1774
+ };
1775
+
1776
+ const dispatchMouseupEvent = (element, window, clientX = 0, clientY = 0) => {
1777
+ const mouseupEvent = new window.MouseEvent('mouseup', {
1778
+ bubbles: true,
1779
+ clientX,
1780
+ clientY
1781
+ });
1782
+ dispatchEvent(element, mouseupEvent);
1783
+ };
1784
+
1785
+ const handleMouseupLocal = (uid, hdId) => {
1786
+ const happyDomInstance = get(uid);
1787
+ if (!happyDomInstance) {
1788
+ return;
2190
1789
  }
2191
- if (state.useSandboxWorker) {
2192
- return handleClickSandbox(state, hdId);
1790
+ const element = happyDomInstance.elementMap.get(hdId);
1791
+ if (!element) {
1792
+ return;
2193
1793
  }
2194
- return handleClickLocal(state, hdId);
1794
+ dispatchMouseupEvent(element, happyDomInstance.window);
1795
+ const elementMap = new Map();
1796
+ set$1(uid, {
1797
+ document: happyDomInstance.document,
1798
+ elementMap,
1799
+ window: happyDomInstance.window
1800
+ });
1801
+ };
1802
+ const handleMouseup = (uid, hdId) => {
1803
+ return handleMouseupLocal(uid, hdId);
2195
1804
  };
2196
1805
 
2197
1806
  function getDefaultExportFromCjs (x) {
@@ -89933,6 +89542,29 @@ const executeScripts = (window, document, scripts, width = 0, height = 0) => {
89933
89542
  }
89934
89543
  };
89935
89544
 
89545
+ const getParsedNodesChildNodeCount = parsedDom => {
89546
+ array(parsedDom);
89547
+ const rootCountFromParse = parsedDom.rootChildCount;
89548
+ if (typeof rootCountFromParse === 'number') {
89549
+ return rootCountFromParse;
89550
+ }
89551
+ let rootChildCount = 0;
89552
+ let i = 0;
89553
+ while (i < parsedDom.length) {
89554
+ rootChildCount++;
89555
+
89556
+ // skip the entire subtree of the current node
89557
+ let toSkip = parsedDom[i].childCount;
89558
+ i++;
89559
+ while (toSkip > 0 && i < parsedDom.length) {
89560
+ toSkip -= 1;
89561
+ toSkip += parsedDom[i].childCount;
89562
+ i++;
89563
+ }
89564
+ }
89565
+ return rootChildCount;
89566
+ };
89567
+
89936
89568
  /* eslint-disable @typescript-eslint/no-floating-promises */
89937
89569
  const observers = new Map();
89938
89570
  const handleMutations = async uid => {
@@ -89947,22 +89579,17 @@ const handleMutations = async uid => {
89947
89579
  elementMap,
89948
89580
  window: happyDomInstance.window
89949
89581
  });
89950
- const {
89951
- newState: state,
89952
- oldState
89953
- } = get$1(uid);
89954
89582
  const parsedDom = serialized.dom;
89955
- const {
89956
- css
89957
- } = serialized;
89958
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
89959
- const updatedState = {
89960
- ...state,
89961
- css,
89962
- parsedDom,
89963
- parsedNodesChildNodeCount
89964
- };
89965
- set$2(uid, oldState, updatedState);
89583
+ // @ts-ignore
89584
+ getParsedNodesChildNodeCount(parsedDom);
89585
+
89586
+ // const updatedState = {
89587
+ // css,
89588
+ // parsedDom,
89589
+ // parsedNodesChildNodeCount,
89590
+ // }
89591
+
89592
+ // TODO notify
89966
89593
  try {
89967
89594
  await invoke('Preview.rerender', uid);
89968
89595
  } catch {
@@ -89986,561 +89613,6 @@ const observe = (uid, document, window) => {
89986
89613
  observers.set(uid, observer);
89987
89614
  };
89988
89615
 
89989
- const None = 0;
89990
- const OpeningAngleBracket = 1;
89991
- const ClosingAngleBracket = 2;
89992
- const TagNameStart = 3;
89993
- const TagNameEnd = 4;
89994
- const Content = 5;
89995
- const ClosingTagSlash = 6;
89996
- const WhitespaceInsideOpeningTag = 7;
89997
- const AttributeName = 8;
89998
- const AttributeEqualSign = 9;
89999
- const AttributeQuoteStart = 10;
90000
- const AttributeValue = 11;
90001
- const AttributeQuoteEnd = 12;
90002
- const WhitespaceAfterClosingTagSlash = 13;
90003
- const WhitespaceAfterOpeningTagOpenAngleBracket = 14;
90004
- const ExclamationMark = 15;
90005
- const Doctype = 16;
90006
- const StartCommentDashes = 17;
90007
- const Comment = 18;
90008
- const EndCommentTag = 19;
90009
- const Text = 20;
90010
- const CommentStart = 21;
90011
-
90012
- const isSelfClosingTag = tag => {
90013
- switch (tag.toLowerCase()) {
90014
- case 'area':
90015
- case 'base':
90016
- case 'col':
90017
- case Br:
90018
- case Hr:
90019
- case Img:
90020
- case Input:
90021
- case 'embed':
90022
- case 'link':
90023
- case 'meta':
90024
- case 'param':
90025
- case 'source':
90026
- case 'track':
90027
- case 'wbr':
90028
- return true;
90029
- default:
90030
- return false;
90031
- }
90032
- };
90033
-
90034
- const parseText = text => {
90035
- return text.replaceAll('&gt;', '>').replaceAll('&lt;', '<').replaceAll('&amp;', '&');
90036
- };
90037
-
90038
- class UnexpectedTokenError extends Error {
90039
- constructor() {
90040
- super('Unexpected token');
90041
- this.name = 'UnexpectedTokenError';
90042
- }
90043
- }
90044
-
90045
- const State = {
90046
- AfterAttributeEqualSign: 8,
90047
- AfterAttributeName: 7,
90048
- AfterAttributeValueClosingQuote: 11,
90049
- AfterAttributeValueInsideDoubleQuote: 10,
90050
- AfterClosingTagName: 5,
90051
- AfterClosingTagSlash: 4,
90052
- AfterExclamationMark: 16,
90053
- AfterOpeningAngleBracket: 2,
90054
- InsideAttributeAfterDoubleQuote: 9,
90055
- InsideComment: 17,
90056
- InsideOpeningTag: 3,
90057
- InsideOpeningTagAfterWhitespace: 6,
90058
- InsideRawTextElement: 18,
90059
- TopLevelContent: 1
90060
- };
90061
-
90062
- // Raw-text elements whose content should not be parsed as HTML
90063
- const RAW_TEXT_ELEMENTS = new Set(['script', 'style']);
90064
- const RE_ANGLE_BRACKET_OPEN = /^</;
90065
- const RE_ANGLE_BRACKET_OPEN_TAG = /^<(?![\s%])/;
90066
- const RE_ANGLE_BRACKET_CLOSE = /^>/;
90067
- const RE_SLASH = /^\//;
90068
- const RE_TAGNAME = /^[a-zA-Z\d$]+/;
90069
- const RE_CONTENT = /^[^<>]+/;
90070
- const RE_WHITESPACE = /^\s+/;
90071
- const RE_ATTRIBUTE_NAME = /^[a-zA-Z\d-]+/;
90072
- const RE_EQUAL_SIGN = /^=/;
90073
- const RE_DOUBLE_QUOTE = /^"/;
90074
- const RE_ATTRIBUTE_VALUE_INSIDE_DOUBLE_QUOTE = /^[^"\n]+/;
90075
- const RE_TEXT = /^[^<>]+/;
90076
- const RE_EXCLAMATION_MARK = /^!/;
90077
- const RE_DASH_DASH = /^--/;
90078
- const RE_DOCTYPE = /^doctype/i;
90079
- const RE_BLOCK_COMMENT_CONTENT = /^[a-zA-Z\s]+/;
90080
- const RE_COMMENT_END = /^-->/;
90081
- const RE_TAG_TEXT = /^[^\s>]+/;
90082
- const RE_ANY_TEXT = /^[^\n]+/;
90083
- const RE_ATTRIBUTE_TEXT = /^[^\n<>/\s]+/;
90084
- const RE_BLOCK_COMMENT_START = /^<!--/;
90085
- const RE_SELF_CLOSING = /^\/>/;
90086
- const tokenizeHtml = text => {
90087
- string(text);
90088
- let state = State.TopLevelContent;
90089
- let index = 0;
90090
- let next;
90091
- const tokens = [];
90092
- let token = None;
90093
- let rawTextTagName = ''; // Track which raw-text element we're inside
90094
- while (index < text.length) {
90095
- const part = text.slice(index);
90096
- switch (state) {
90097
- case State.AfterAttributeEqualSign:
90098
- if (next = part.match(RE_DOUBLE_QUOTE)) {
90099
- token = AttributeQuoteStart;
90100
- state = State.InsideAttributeAfterDoubleQuote;
90101
- } else if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
90102
- token = ClosingAngleBracket;
90103
- state = State.TopLevelContent;
90104
- } else if (next = part.match(RE_ATTRIBUTE_TEXT)) {
90105
- token = AttributeValue;
90106
- state = State.InsideOpeningTag;
90107
- } else {
90108
- throw new UnexpectedTokenError();
90109
- }
90110
- break;
90111
- case State.AfterAttributeName:
90112
- if (next = part.match(RE_EQUAL_SIGN)) {
90113
- token = AttributeEqualSign;
90114
- state = State.AfterAttributeEqualSign;
90115
- } else if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
90116
- token = ClosingAngleBracket;
90117
- state = State.TopLevelContent;
90118
- } else if (next = part.match(RE_WHITESPACE)) {
90119
- token = WhitespaceInsideOpeningTag;
90120
- state = State.InsideOpeningTagAfterWhitespace;
90121
- } else if (next = part.match(RE_ANGLE_BRACKET_OPEN)) {
90122
- token = OpeningAngleBracket;
90123
- state = State.AfterOpeningAngleBracket;
90124
- } else {
90125
- text.slice(index); // ?
90126
- throw new UnexpectedTokenError();
90127
- }
90128
- break;
90129
- case State.AfterAttributeValueClosingQuote:
90130
- if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
90131
- token = ClosingAngleBracket;
90132
- state = State.TopLevelContent;
90133
- } else if (next = part.match(RE_WHITESPACE)) {
90134
- token = WhitespaceInsideOpeningTag;
90135
- state = State.InsideOpeningTagAfterWhitespace;
90136
- } else if (next = part.match(RE_SELF_CLOSING)) {
90137
- token = ClosingAngleBracket;
90138
- state = State.TopLevelContent;
90139
- } else {
90140
- throw new UnexpectedTokenError();
90141
- }
90142
- break;
90143
- case State.AfterAttributeValueInsideDoubleQuote:
90144
- if (next = part.match(RE_DOUBLE_QUOTE)) {
90145
- token = AttributeQuoteEnd;
90146
- state = State.AfterAttributeValueClosingQuote;
90147
- } else {
90148
- throw new UnexpectedTokenError();
90149
- }
90150
- break;
90151
- case State.AfterClosingTagName:
90152
- if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
90153
- token = ClosingAngleBracket;
90154
- state = State.TopLevelContent;
90155
- } else if (next = part.match(RE_WHITESPACE)) {
90156
- token = Content;
90157
- state = State.TopLevelContent;
90158
- } else {
90159
- throw new UnexpectedTokenError();
90160
- }
90161
- break;
90162
- case State.AfterClosingTagSlash:
90163
- if (next = part.match(RE_TAGNAME)) {
90164
- token = TagNameEnd;
90165
- state = State.AfterClosingTagName;
90166
- } else if (next = part.match(RE_WHITESPACE)) {
90167
- token = WhitespaceAfterClosingTagSlash;
90168
- state = State.TopLevelContent;
90169
- } else if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
90170
- token = ClosingAngleBracket;
90171
- state = State.TopLevelContent;
90172
- } else {
90173
- throw new UnexpectedTokenError();
90174
- }
90175
- break;
90176
- case State.AfterExclamationMark:
90177
- if (next = part.match(RE_DASH_DASH)) {
90178
- token = StartCommentDashes;
90179
- state = State.InsideComment;
90180
- } else if (next = part.match(RE_DOCTYPE)) {
90181
- token = Doctype;
90182
- state = State.InsideOpeningTag;
90183
- } else {
90184
- text.slice(index); // ?
90185
- throw new UnexpectedTokenError();
90186
- }
90187
- break;
90188
- case State.AfterOpeningAngleBracket:
90189
- if (next = part.match(RE_TAGNAME)) {
90190
- token = TagNameStart;
90191
- state = State.InsideOpeningTag;
90192
- // Track raw-text elements so we can switch to raw content mode after >
90193
- if (RAW_TEXT_ELEMENTS.has(next[0].toLowerCase())) {
90194
- rawTextTagName = next[0].toLowerCase();
90195
- }
90196
- } else if (next = part.match(RE_SLASH)) {
90197
- token = ClosingTagSlash;
90198
- state = State.AfterClosingTagSlash;
90199
- } else if (next = part.match(RE_WHITESPACE)) {
90200
- token = WhitespaceAfterOpeningTagOpenAngleBracket;
90201
- state = State.TopLevelContent;
90202
- } else if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
90203
- token = ClosingAngleBracket;
90204
- state = State.TopLevelContent;
90205
- } else if (next = part.match(RE_EXCLAMATION_MARK)) {
90206
- token = ExclamationMark;
90207
- state = State.AfterExclamationMark;
90208
- } else if (next = part.match(RE_ANY_TEXT)) {
90209
- token = Text;
90210
- state = State.TopLevelContent;
90211
- } else {
90212
- text.slice(index); // ?
90213
- throw new UnexpectedTokenError();
90214
- }
90215
- break;
90216
- case State.InsideAttributeAfterDoubleQuote:
90217
- if (next = text.slice(index).match(RE_ATTRIBUTE_VALUE_INSIDE_DOUBLE_QUOTE)) {
90218
- token = AttributeValue;
90219
- state = State.AfterAttributeValueInsideDoubleQuote;
90220
- } else if (next = part.match(RE_DOUBLE_QUOTE)) {
90221
- token = AttributeQuoteEnd;
90222
- state = State.AfterAttributeValueClosingQuote;
90223
- } else {
90224
- throw new UnexpectedTokenError();
90225
- }
90226
- break;
90227
- case State.InsideComment:
90228
- if (next = part.match(RE_BLOCK_COMMENT_CONTENT)) {
90229
- token = Comment;
90230
- state = State.InsideComment;
90231
- } else if (next = part.match(RE_COMMENT_END)) {
90232
- token = EndCommentTag;
90233
- state = State.TopLevelContent;
90234
- } else {
90235
- text.slice(index); // ?
90236
- throw new UnexpectedTokenError();
90237
- }
90238
- break;
90239
- case State.InsideOpeningTag:
90240
- if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
90241
- token = ClosingAngleBracket;
90242
- state = State.TopLevelContent;
90243
- } else if (next = part.match(RE_WHITESPACE)) {
90244
- token = WhitespaceInsideOpeningTag;
90245
- state = State.InsideOpeningTagAfterWhitespace;
90246
- } else if (next = part.match(RE_TAG_TEXT)) {
90247
- token = Text;
90248
- state = State.TopLevelContent;
90249
- } else {
90250
- throw new UnexpectedTokenError();
90251
- }
90252
- break;
90253
- case State.InsideOpeningTagAfterWhitespace:
90254
- if (next = part.match(RE_ATTRIBUTE_NAME)) {
90255
- token = AttributeName;
90256
- state = State.AfterAttributeName;
90257
- } else if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
90258
- token = ClosingAngleBracket;
90259
- state = State.TopLevelContent;
90260
- } else if (next = part.match(RE_SELF_CLOSING)) {
90261
- token = ClosingAngleBracket;
90262
- state = State.TopLevelContent;
90263
- } else if (next = part.match(RE_TEXT)) {
90264
- token = AttributeName;
90265
- state = State.AfterAttributeName;
90266
- } else {
90267
- text.slice(index).match(RE_TEXT); // ?
90268
- text.slice(index); // ?
90269
- throw new UnexpectedTokenError();
90270
- }
90271
- break;
90272
- case State.InsideRawTextElement:
90273
- {
90274
- // Match everything up to the closing tag for the current raw-text element
90275
- const closingTagPattern = new RegExp(`^([\\s\\S]*?)(<\\/${rawTextTagName}>)`, 'i');
90276
- const rawMatch = part.match(closingTagPattern);
90277
- if (rawMatch) {
90278
- // Emit content before the closing tag (if any)
90279
- if (rawMatch[1].length > 0) {
90280
- tokens.push({
90281
- text: rawMatch[1],
90282
- type: Content
90283
- });
90284
- index += rawMatch[1].length;
90285
- }
90286
- // Now emit the closing tag tokens: <, /, tagname, >
90287
- // < token
90288
- tokens.push({
90289
- text: '<',
90290
- type: OpeningAngleBracket
90291
- });
90292
- index += 1;
90293
- // / token
90294
- tokens.push({
90295
- text: '/',
90296
- type: ClosingTagSlash
90297
- });
90298
- index += 1;
90299
- // tagname token
90300
- tokens.push({
90301
- text: rawTextTagName,
90302
- type: TagNameEnd
90303
- });
90304
- index += rawTextTagName.length;
90305
- // > token
90306
- tokens.push({
90307
- text: '>',
90308
- type: ClosingAngleBracket
90309
- });
90310
- index += 1;
90311
- rawTextTagName = '';
90312
- state = State.TopLevelContent;
90313
- continue;
90314
- }
90315
- // No closing tag found — consume everything as content
90316
- next = [part];
90317
- token = Content;
90318
- rawTextTagName = '';
90319
- state = State.TopLevelContent;
90320
- break;
90321
- }
90322
- case State.TopLevelContent:
90323
- if (next = part.match(RE_ANGLE_BRACKET_OPEN_TAG)) {
90324
- token = OpeningAngleBracket;
90325
- state = State.AfterOpeningAngleBracket;
90326
- } else if (next = part.match(RE_CONTENT)) {
90327
- token = Content;
90328
- state = State.TopLevelContent;
90329
- } else if (next = part.match(RE_BLOCK_COMMENT_START)) {
90330
- token = CommentStart;
90331
- state = State.InsideComment;
90332
- } else if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
90333
- token = Content;
90334
- state = State.TopLevelContent;
90335
- } else if (next = part.match(RE_ANGLE_BRACKET_OPEN)) {
90336
- token = Text;
90337
- state = State.TopLevelContent;
90338
- } else {
90339
- throw new UnexpectedTokenError();
90340
- }
90341
- break;
90342
- default:
90343
- throw new UnexpectedTokenError();
90344
- }
90345
- const tokenText = next[0];
90346
- // After closing angle bracket of a raw-text element opening tag,
90347
- // switch to raw text content mode instead of top-level content
90348
- if (rawTextTagName && token === ClosingAngleBracket && state === State.TopLevelContent) {
90349
- state = State.InsideRawTextElement;
90350
- }
90351
- tokens.push({
90352
- text: tokenText,
90353
- type: token
90354
- });
90355
- index += tokenText.length;
90356
- }
90357
- return tokens;
90358
- };
90359
-
90360
- // Tags that should be completely skipped (both tag and content)
90361
- const TAGS_TO_SKIP_COMPLETELY = new Set(['meta', 'title']);
90362
-
90363
- // Tags that should have their opening/closing tags skipped but content processed
90364
- const TAGS_TO_SKIP_TAG_ONLY = new Set(['html', 'head']);
90365
-
90366
- // Tags where we capture content as CSS
90367
- const TAGS_TO_CAPTURE_AS_CSS = new Set(['style']);
90368
-
90369
- // Tags where we capture content as JavaScript
90370
- const TAGS_TO_CAPTURE_AS_JS = new Set(['script']);
90371
- const parseHtml = (html, allowedAttributes = [], defaultAllowedAttributes = []) => {
90372
- string(html);
90373
- array(allowedAttributes);
90374
- array(defaultAllowedAttributes);
90375
-
90376
- // Combine default allowed attributes with any additional ones provided
90377
- const allAllowedAttributes = new Set([...defaultAllowedAttributes, ...allowedAttributes]);
90378
- const useBuiltInDefaults = allowedAttributes.length === 0;
90379
- const tokens = tokenizeHtml(html);
90380
- const dom = [];
90381
- const css = [];
90382
- const scripts = [];
90383
- const root = {
90384
- childCount: 0,
90385
- type: 0
90386
- };
90387
- let current = root;
90388
- const stack = [root];
90389
- const tagStack = []; // Track tag names to match closing tags
90390
- let attributeName = '';
90391
- let lastTagWasSelfClosing = false;
90392
- let skipDepth = 0; // Track how many levels deep we are in skipped content
90393
- let captureCss = false; // Track if we're inside a style tag
90394
- let cssContent = ''; // Accumulate CSS content
90395
- let captureJs = false; // Track if we're inside a script tag
90396
- let jsContent = ''; // Accumulate JavaScript content
90397
-
90398
- for (const token of tokens) {
90399
- switch (token.type) {
90400
- case AttributeName:
90401
- if (skipDepth === 0 && !captureCss && !captureJs) {
90402
- attributeName = token.text;
90403
- }
90404
- break;
90405
- case AttributeValue:
90406
- if (skipDepth === 0 && !captureCss && !captureJs && (allAllowedAttributes.has(attributeName) || useBuiltInDefaults && isDefaultAllowedAttribute(attributeName, defaultAllowedAttributes))) {
90407
- let finalAttributeName = attributeName;
90408
- if (attributeName === 'class') finalAttributeName = 'className';else if (attributeName === 'type') finalAttributeName = 'inputType';
90409
- current[finalAttributeName] = token.text;
90410
- }
90411
- attributeName = '';
90412
- break;
90413
- case ClosingAngleBracket:
90414
- if (skipDepth === 0 && !captureCss && !captureJs) {
90415
- // Handle boolean attributes (attributes without values)
90416
- if (attributeName && (allAllowedAttributes.has(attributeName) || useBuiltInDefaults && isDefaultAllowedAttribute(attributeName, defaultAllowedAttributes))) {
90417
- let finalAttributeName = attributeName;
90418
- if (attributeName === 'class') finalAttributeName = 'className';else if (attributeName === 'type') finalAttributeName = 'inputType';
90419
- current[finalAttributeName] = attributeName;
90420
- }
90421
- attributeName = '';
90422
- // Return to parent if the current tag is self-closing
90423
- if (lastTagWasSelfClosing) {
90424
- current = stack.at(-1) || root;
90425
- lastTagWasSelfClosing = false;
90426
- }
90427
- }
90428
- break;
90429
- case Content:
90430
- if (captureCss) {
90431
- cssContent += token.text;
90432
- } else if (captureJs) {
90433
- jsContent += token.text;
90434
- } else if (skipDepth === 0) {
90435
- current.childCount++;
90436
- dom.push(text(parseText(token.text)));
90437
- }
90438
- break;
90439
- case Doctype:
90440
- // Ignore DOCTYPE - it's parsed but not rendered since we're in a div
90441
- break;
90442
- case TagNameEnd:
90443
- const tagNameToClose = tagStack.pop()?.toLowerCase() || '';
90444
- if (TAGS_TO_CAPTURE_AS_CSS.has(tagNameToClose)) {
90445
- // Finished capturing CSS
90446
- if (cssContent.trim()) {
90447
- css.push(cssContent);
90448
- }
90449
- cssContent = '';
90450
- captureCss = false;
90451
- } else if (TAGS_TO_CAPTURE_AS_JS.has(tagNameToClose)) {
90452
- // Finished capturing JavaScript
90453
- if (jsContent.trim()) {
90454
- scripts.push(jsContent);
90455
- }
90456
- jsContent = '';
90457
- captureJs = false;
90458
- } else if (TAGS_TO_SKIP_COMPLETELY.has(tagNameToClose)) {
90459
- // We were skipping this content, so decrement skipDepth
90460
- skipDepth--;
90461
- } else if (TAGS_TO_SKIP_TAG_ONLY.has(tagNameToClose)) ; else {
90462
- // Normal tag - pop from stack
90463
- if (stack.length > 1) {
90464
- stack.pop();
90465
- }
90466
- current = stack.at(-1) || root;
90467
- }
90468
- break;
90469
- case TagNameStart:
90470
- const tagNameLower = token.text.toLowerCase();
90471
- lastTagWasSelfClosing = isSelfClosingTag(token.text);
90472
-
90473
- // Check if this tag captures CSS content
90474
- if (TAGS_TO_CAPTURE_AS_CSS.has(tagNameLower)) {
90475
- captureCss = true;
90476
- cssContent = '';
90477
- tagStack.push(token.text);
90478
- }
90479
- // Check if this tag captures JavaScript content
90480
- else if (TAGS_TO_CAPTURE_AS_JS.has(tagNameLower)) {
90481
- captureJs = true;
90482
- jsContent = '';
90483
- tagStack.push(token.text);
90484
- }
90485
- // Check if this tag should be completely skipped (meta, title)
90486
- else if (TAGS_TO_SKIP_COMPLETELY.has(tagNameLower)) {
90487
- if (!lastTagWasSelfClosing) {
90488
- // For non-self-closing tags like title, mark as skipped
90489
- skipDepth++;
90490
- tagStack.push(token.text);
90491
- }
90492
- // For self-closing tags like meta, we just skip them without tracking
90493
- }
90494
- // Check if this tag should have its opening/closing tags skipped (html, head)
90495
- else if (TAGS_TO_SKIP_TAG_ONLY.has(tagNameLower)) {
90496
- if (!lastTagWasSelfClosing) {
90497
- // Track the tag name for matching the closing tag
90498
- tagStack.push(token.text);
90499
- }
90500
- }
90501
- // Normal tag processing
90502
- else if (skipDepth === 0) {
90503
- current.childCount++;
90504
- const newNode = {
90505
- childCount: 0,
90506
- type: getVirtualDomTag(token.text)
90507
- };
90508
- dom.push(newNode);
90509
- current = newNode;
90510
- if (!lastTagWasSelfClosing) {
90511
- stack.push(current);
90512
- tagStack.push(token.text);
90513
- }
90514
- }
90515
- break;
90516
- case WhitespaceInsideOpeningTag:
90517
- if (skipDepth === 0 && !captureCss && !captureJs &&
90518
- // Handle boolean attributes (attributes without values)
90519
- attributeName && (allAllowedAttributes.has(attributeName) || useBuiltInDefaults && isDefaultAllowedAttribute(attributeName, defaultAllowedAttributes))) {
90520
- let finalAttributeName = attributeName;
90521
- if (attributeName === 'class') finalAttributeName = 'className';else if (attributeName === 'type') finalAttributeName = 'inputType';
90522
- current[finalAttributeName] = attributeName;
90523
- }
90524
- attributeName = '';
90525
- break;
90526
- }
90527
- }
90528
- try {
90529
- Object.defineProperty(dom, 'rootChildCount', {
90530
- configurable: true,
90531
- enumerable: false,
90532
- value: root.childCount
90533
- });
90534
- } catch {
90535
- dom.rootChildCount = root.childCount;
90536
- }
90537
- return {
90538
- css,
90539
- dom,
90540
- scripts
90541
- };
90542
- };
90543
-
90544
89616
  /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
90545
89617
 
90546
89618
  const states = new Map();
@@ -90559,6 +89631,8 @@ const toNumber = value => {
90559
89631
  return 0;
90560
89632
  };
90561
89633
 
89634
+ /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
89635
+
90562
89636
  const patchCanvasElements = async (document, uid) => {
90563
89637
  const canvasElements = document.querySelectorAll('canvas');
90564
89638
  if (canvasElements.length === 0) {
@@ -90569,17 +89643,22 @@ const patchCanvasElements = async (document, uid) => {
90569
89643
  const element = canvasElements[i];
90570
89644
  const width = toNumber(element.getAttribute('width') || 300);
90571
89645
  const height = toNumber(element.getAttribute('height') || 300);
89646
+ // @ts-ignore
90572
89647
  element.width = width;
89648
+ // @ts-ignore
90573
89649
  element.height = height;
90574
89650
  const {
90575
89651
  canvasId,
90576
89652
  offscreenCanvas
90577
- } = await getOffscreenCanvas(width, height);
89653
+ } = await getOffscreenCanvas(uid, width, height);
90578
89654
  const dataId = String(canvasId);
89655
+ // @ts-ignore
90579
89656
  element.__canvasId = canvasId;
89657
+ // @ts-ignore
90580
89658
  element.__offscreenCanvas = offscreenCanvas;
90581
89659
  element.dataset.id = dataId;
90582
89660
  const context = offscreenCanvas.getContext('2d');
89661
+ // @ts-ignore
90583
89662
  element.getContext = contextType => {
90584
89663
  if (contextType === '2d') {
90585
89664
  return context;
@@ -90601,6 +89680,7 @@ const patchCanvasElements = async (document, uid) => {
90601
89680
  get: () => widthValue,
90602
89681
  set: newWidth => {
90603
89682
  widthValue = toNumber(newWidth);
89683
+ // @ts-ignore
90604
89684
  element.__offscreenCanvas.width = widthValue;
90605
89685
  }
90606
89686
  });
@@ -90613,6 +89693,7 @@ const patchCanvasElements = async (document, uid) => {
90613
89693
  get: () => heightValue,
90614
89694
  set: newHeight => {
90615
89695
  heightValue = toNumber(newHeight);
89696
+ // @ts-ignore
90616
89697
  element.__offscreenCanvas.height = heightValue;
90617
89698
  }
90618
89699
  });
@@ -90629,729 +89710,44 @@ const patchCanvasElements = async (document, uid) => {
90629
89710
  });
90630
89711
  };
90631
89712
 
90632
- /* eslint-disable prefer-destructuring */
90633
-
90634
- const updateContent = async (state, uri) => {
89713
+ const updateContent = async (uid, width, height, content, scripts) => {
90635
89714
  try {
90636
- // Read the file content using RendererWorker RPC
90637
- const content = await readFile(uri);
90638
-
90639
- // Parse the content into virtual DOM and CSS
90640
- const parseResult = parseHtml(content);
90641
- let parsedDom = parseResult.dom;
90642
- let {
90643
- css
90644
- } = parseResult;
90645
89715
  const {
90646
- scripts
90647
- } = parseResult;
90648
-
90649
- // If scripts are present and not using sandbox worker, execute them via happy-dom and re-serialize the DOM
90650
- if (scripts.length > 0 && !state.useSandboxWorker) {
90651
- try {
90652
- const {
90653
- document: happyDomDocument,
90654
- window: happyDomWindow
90655
- } = createWindow(content);
90656
- await patchCanvasElements(happyDomDocument, state.uid);
90657
- executeScripts(happyDomWindow, happyDomDocument, scripts, state.width, state.height);
90658
- const elementMap = new Map();
90659
- const serialized = serialize(happyDomDocument, elementMap);
90660
- parsedDom = serialized.dom;
90661
- css = serialized.css;
90662
- set$1(state.uid, {
90663
- document: happyDomDocument,
90664
- elementMap,
90665
- window: happyDomWindow
90666
- });
90667
- observe(state.uid, happyDomDocument, happyDomWindow);
90668
- } catch (error) {
90669
- console.error(error);
90670
- // If script execution fails, fall back to static HTML parsing
90671
- }
90672
- }
90673
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
89716
+ document: happyDomDocument,
89717
+ window: happyDomWindow
89718
+ } = createWindow(content);
89719
+ await patchCanvasElements(happyDomDocument, uid);
89720
+ executeScripts(happyDomWindow, happyDomDocument, scripts, width, height);
89721
+ const elementMap = new Map();
89722
+ set$1(uid, {
89723
+ document: happyDomDocument,
89724
+ elementMap,
89725
+ window: happyDomWindow
89726
+ });
89727
+ observe(uid, happyDomDocument, happyDomWindow);
90674
89728
  return {
90675
- content,
90676
- css,
90677
- errorMessage: '',
90678
- parsedDom,
90679
- parsedNodesChildNodeCount,
90680
- scripts
89729
+ errorMessage: ''
90681
89730
  };
90682
89731
  } catch (error) {
90683
89732
  // If file reading or parsing fails, return empty content and parsedDom with error message
90684
89733
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
90685
89734
  return {
90686
- content: '',
90687
- css: [],
90688
- errorMessage,
90689
- parsedDom: [],
90690
- parsedNodesChildNodeCount: 0,
90691
- scripts: []
89735
+ errorMessage
90692
89736
  };
90693
89737
  }
90694
89738
  };
90695
89739
 
90696
- const handleFileEdited = async state => {
90697
- const {
90698
- content,
90699
- css,
90700
- errorMessage,
90701
- parsedDom,
90702
- parsedNodesChildNodeCount,
90703
- scripts
90704
- } = await updateContent(state, state.uri);
90705
- return {
90706
- ...state,
90707
- content,
90708
- css,
90709
- errorMessage,
90710
- parsedDom,
90711
- parsedNodesChildNodeCount,
90712
- scripts
90713
- };
90714
- };
90715
-
90716
- const dispatchInputEvent = (element, window) => {
90717
- const inputEvent = new window.Event('input', {
90718
- bubbles: true
90719
- });
90720
- dispatchEvent(element, inputEvent);
90721
- };
90722
-
90723
- const handleInputSandbox = async (state, hdId, value) => {
90724
- const {
90725
- sandboxRpc,
90726
- uid
90727
- } = state;
90728
- await sandboxRpc.invoke('SandBox.handleInput', uid, hdId, value);
90729
- const serialized = await sandboxRpc.invoke('SandBox.getSerializedDom', uid);
90730
- const parsedDom = serialized.dom;
90731
- const {
90732
- css
90733
- } = serialized;
90734
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
90735
- return {
90736
- ...state,
90737
- css,
90738
- parsedDom,
90739
- parsedNodesChildNodeCount
90740
- };
90741
- };
90742
- const handleInputLocal = (state, hdId, value) => {
90743
- const happyDomInstance = get(state.uid);
90744
- if (!happyDomInstance) {
90745
- return state;
90746
- }
90747
- const element = happyDomInstance.elementMap.get(hdId);
90748
- if (!element) {
90749
- return state;
90750
- }
90751
- element.value = value;
90752
- dispatchInputEvent(element, happyDomInstance.window);
90753
- const elementMap = new Map();
90754
- const serialized = serialize(happyDomInstance.document, elementMap);
90755
- set$1(state.uid, {
90756
- document: happyDomInstance.document,
90757
- elementMap,
90758
- window: happyDomInstance.window
90759
- });
90760
- const parsedDom = serialized.dom;
90761
- const {
90762
- css
90763
- } = serialized;
90764
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
90765
- return {
90766
- ...state,
90767
- css,
90768
- parsedDom,
90769
- parsedNodesChildNodeCount
90770
- };
90771
- };
90772
- const handleInput = (state, hdId, value) => {
90773
- if (!hdId) {
90774
- return state;
90775
- }
90776
- if (state.useSandboxWorker) {
90777
- return handleInputSandbox(state, hdId, value);
90778
- }
90779
- return handleInputLocal(state, hdId, value);
90780
- };
90781
-
90782
- const dispatchKeydownEvent = (element, window, key, code) => {
90783
- const keydownEvent = new window.KeyboardEvent('keydown', {
90784
- bubbles: true,
90785
- code,
90786
- key
90787
- });
90788
- dispatchEvent(element, keydownEvent);
90789
- };
90790
-
90791
- const handleKeydownSandbox = async (state, hdId, key, code) => {
90792
- const {
90793
- sandboxRpc,
90794
- uid
90795
- } = state;
90796
- await sandboxRpc.invoke('SandBox.handleKeyDown', uid, hdId, key, code);
90797
- const serialized = await sandboxRpc.invoke('SandBox.getSerializedDom', uid);
90798
- const parsedDom = serialized.dom;
90799
- const {
90800
- css
90801
- } = serialized;
90802
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
90803
- return {
90804
- ...state,
90805
- css,
90806
- parsedDom,
90807
- parsedNodesChildNodeCount
90808
- };
90809
- };
90810
- const handleKeydownLocal = (state, hdId, key, code) => {
90811
- const happyDomInstance = get(state.uid);
90812
- if (!happyDomInstance) {
90813
- return state;
90814
- }
90815
- const element = hdId ? happyDomInstance.elementMap.get(hdId) : happyDomInstance.document;
90816
- if (!element) {
90817
- return state;
90818
- }
90819
- dispatchKeydownEvent(element, happyDomInstance.window, key, code);
90820
- const elementMap = new Map();
90821
- const serialized = serialize(happyDomInstance.document, elementMap);
90822
- set$1(state.uid, {
90823
- document: happyDomInstance.document,
90824
- elementMap,
90825
- window: happyDomInstance.window
90826
- });
90827
- const parsedDom = serialized.dom;
90828
- const {
90829
- css
90830
- } = serialized;
90831
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
90832
- return {
90833
- ...state,
90834
- css,
90835
- parsedDom,
90836
- parsedNodesChildNodeCount
90837
- };
90838
- };
90839
- const handleKeydown = (state, hdId, key, code) => {
90840
- if (state.useSandboxWorker) {
90841
- return handleKeydownSandbox(state, hdId, key, code);
90842
- }
90843
- return handleKeydownLocal(state, hdId, key, code);
90844
- };
90845
-
90846
- const dispatchKeyupEvent = (element, window, key, code) => {
90847
- const keyupEvent = new window.KeyboardEvent('keyup', {
90848
- bubbles: true,
90849
- code,
90850
- key
90851
- });
90852
- dispatchEvent(element, keyupEvent);
90853
- };
90854
-
90855
- const handleKeyupSandbox = async (state, hdId, key, code) => {
90856
- const {
90857
- sandboxRpc,
90858
- uid
90859
- } = state;
90860
- await sandboxRpc.invoke('SandBox.handleKeyUp', uid, hdId, key, code);
90861
- const serialized = await sandboxRpc.invoke('SandBox.getSerializedDom', uid);
90862
- const parsedDom = serialized.dom;
90863
- const {
90864
- css
90865
- } = serialized;
90866
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
90867
- return {
90868
- ...state,
90869
- css,
90870
- parsedDom,
90871
- parsedNodesChildNodeCount
90872
- };
90873
- };
90874
- const handleKeyupLocal = (state, hdId, key, code) => {
90875
- const happyDomInstance = get(state.uid);
90876
- if (!happyDomInstance) {
90877
- return state;
90878
- }
90879
- const element = hdId ? happyDomInstance.elementMap.get(hdId) : happyDomInstance.document;
90880
- if (!element) {
90881
- return state;
90882
- }
90883
- dispatchKeyupEvent(element, happyDomInstance.window, key, code);
90884
- const elementMap = new Map();
90885
- const serialized = serialize(happyDomInstance.document, elementMap);
90886
- set$1(state.uid, {
90887
- document: happyDomInstance.document,
90888
- elementMap,
90889
- window: happyDomInstance.window
90890
- });
90891
- const parsedDom = serialized.dom;
90892
- const {
90893
- css
90894
- } = serialized;
90895
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
90896
- return {
90897
- ...state,
90898
- css,
90899
- parsedDom,
90900
- parsedNodesChildNodeCount
90901
- };
90902
- };
90903
- const handleKeyup = (state, hdId, key, code) => {
90904
- if (state.useSandboxWorker) {
90905
- return handleKeyupSandbox(state, hdId, key, code);
90906
- }
90907
- return handleKeyupLocal(state, hdId, key, code);
90908
- };
90909
-
90910
- const handleMessagePort = async port => {
90911
- await PlainMessagePortRpc.create({
90912
- commandMap: {},
90913
- messagePort: port
90914
- });
90915
- };
90916
-
90917
- const dispatchMousedownEvent = (element, window, clientX = 0, clientY = 0) => {
90918
- const mousedownEvent = new window.MouseEvent('mousedown', {
90919
- bubbles: true,
90920
- clientX,
90921
- clientY
90922
- });
90923
- dispatchEvent(element, mousedownEvent);
90924
- };
90925
-
90926
- const handleMousedownSandbox = async (state, hdId) => {
90927
- const {
90928
- sandboxRpc,
90929
- uid
90930
- } = state;
90931
- await sandboxRpc.invoke('SandBox.handleMousedown', uid, hdId);
90932
- const serialized = await sandboxRpc.invoke('SandBox.getSerializedDom', uid);
90933
- const parsedDom = serialized.dom;
90934
- const {
90935
- css
90936
- } = serialized;
90937
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
90938
- return {
90939
- ...state,
90940
- css,
90941
- parsedDom,
90942
- parsedNodesChildNodeCount
90943
- };
90944
- };
90945
- const handleMousedownLocal = (state, hdId, clientX, clientY) => {
90946
- const happyDomInstance = get(state.uid);
90947
- if (!happyDomInstance) {
90948
- return state;
90949
- }
90950
- const element = happyDomInstance.elementMap.get(hdId);
90951
- if (!element) {
90952
- return state;
90953
- }
90954
- const adjustedClientX = clientX - state.x;
90955
- const adjustedClientY = clientY - state.y;
90956
- dispatchMousedownEvent(element, happyDomInstance.window, adjustedClientX, adjustedClientY);
90957
- const elementMap = new Map();
90958
- const serialized = serialize(happyDomInstance.document, elementMap);
90959
- set$1(state.uid, {
90960
- document: happyDomInstance.document,
90961
- elementMap,
90962
- window: happyDomInstance.window
90963
- });
90964
- const parsedDom = serialized.dom;
90965
- const {
90966
- css
90967
- } = serialized;
90968
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
90969
- return {
90970
- ...state,
90971
- css,
90972
- parsedDom,
90973
- parsedNodesChildNodeCount
90974
- };
90975
- };
90976
- const handleMousedown = (state, hdId, clientX, clientY) => {
90977
- if (!hdId) {
90978
- return state;
90979
- }
90980
- if (state.useSandboxWorker) {
90981
- return handleMousedownSandbox(state, hdId);
90982
- }
90983
- return handleMousedownLocal(state, hdId, clientX, clientY);
90984
- };
90985
-
90986
- const dispatchMousemoveEvent = (element, window, clientX = 0, clientY = 0) => {
90987
- const mousemoveEvent = new window.MouseEvent('mousemove', {
90988
- bubbles: true,
90989
- clientX,
90990
- clientY
90991
- });
90992
- dispatchEvent(element, mousemoveEvent);
90993
- };
90994
-
90995
- const handleMousemoveSandbox = async (state, hdId) => {
90996
- const {
90997
- sandboxRpc,
90998
- uid
90999
- } = state;
91000
- await sandboxRpc.invoke('SandBox.handleMousemove', uid, hdId);
91001
- const serialized = await sandboxRpc.invoke('SandBox.getSerializedDom', uid);
91002
- const parsedDom = serialized.dom;
91003
- const {
91004
- css
91005
- } = serialized;
91006
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
91007
- return {
91008
- ...state,
91009
- css,
91010
- parsedDom,
91011
- parsedNodesChildNodeCount
91012
- };
91013
- };
91014
- const handleMousemoveLocal = (state, hdId, clientX, clientY) => {
91015
- const happyDomInstance = get(state.uid);
91016
- if (!happyDomInstance) {
91017
- return state;
91018
- }
91019
- const element = happyDomInstance.elementMap.get(hdId);
91020
- if (!element) {
91021
- return state;
91022
- }
91023
- const adjustedClientX = clientX - state.x;
91024
- const adjustedClientY = clientY - state.y;
91025
- dispatchMousemoveEvent(element, happyDomInstance.window, adjustedClientX, adjustedClientY);
91026
- const elementMap = new Map();
91027
- const serialized = serialize(happyDomInstance.document, elementMap);
91028
- set$1(state.uid, {
91029
- document: happyDomInstance.document,
91030
- elementMap,
91031
- window: happyDomInstance.window
91032
- });
91033
- const parsedDom = serialized.dom;
91034
- const {
91035
- css
91036
- } = serialized;
91037
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
91038
- return {
91039
- ...state,
91040
- css,
91041
- parsedDom,
91042
- parsedNodesChildNodeCount
91043
- };
91044
- };
91045
- const handleMousemove = (state, hdId, clientX, clientY) => {
91046
- if (!hdId) {
91047
- return state;
91048
- }
91049
- if (state.useSandboxWorker) {
91050
- return handleMousemoveSandbox(state, hdId);
91051
- }
91052
- return handleMousemoveLocal(state, hdId, clientX, clientY);
91053
- };
91054
-
91055
- const dispatchMouseupEvent = (element, window, clientX = 0, clientY = 0) => {
91056
- const mouseupEvent = new window.MouseEvent('mouseup', {
91057
- bubbles: true,
91058
- clientX,
91059
- clientY
91060
- });
91061
- dispatchEvent(element, mouseupEvent);
91062
- };
91063
-
91064
- const handleMouseupSandbox = async (state, hdId) => {
91065
- const {
91066
- sandboxRpc,
91067
- uid
91068
- } = state;
91069
- await sandboxRpc.invoke('SandBox.handleMouseup', uid, hdId);
91070
- const serialized = await sandboxRpc.invoke('SandBox.getSerializedDom', uid);
91071
- const parsedDom = serialized.dom;
91072
- const {
91073
- css
91074
- } = serialized;
91075
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
91076
- return {
91077
- ...state,
91078
- css,
91079
- parsedDom,
91080
- parsedNodesChildNodeCount
91081
- };
91082
- };
91083
- const handleMouseupLocal = (state, hdId) => {
91084
- const happyDomInstance = get(state.uid);
91085
- if (!happyDomInstance) {
91086
- return state;
91087
- }
91088
- const element = happyDomInstance.elementMap.get(hdId);
91089
- if (!element) {
91090
- return state;
91091
- }
91092
- dispatchMouseupEvent(element, happyDomInstance.window);
91093
- const elementMap = new Map();
91094
- const serialized = serialize(happyDomInstance.document, elementMap);
91095
- set$1(state.uid, {
91096
- document: happyDomInstance.document,
91097
- elementMap,
91098
- window: happyDomInstance.window
91099
- });
91100
- const parsedDom = serialized.dom;
91101
- const {
91102
- css
91103
- } = serialized;
91104
- const parsedNodesChildNodeCount = getParsedNodesChildNodeCount(parsedDom);
91105
- return {
91106
- ...state,
91107
- css,
91108
- parsedDom,
91109
- parsedNodesChildNodeCount
91110
- };
91111
- };
91112
- const handleMouseup = (state, hdId) => {
91113
- if (!hdId) {
91114
- return state;
91115
- }
91116
- if (state.useSandboxWorker) {
91117
- return handleMouseupSandbox(state, hdId);
91118
- }
91119
- return handleMouseupLocal(state, hdId);
91120
- };
91121
-
91122
- const loadContent = async state => {
89740
+ const loadContent = async (uid, width, height, content, scripts) => {
91123
89741
  // Try to register to receive editor change notifications from the editor worker.
91124
89742
  // Use dynamic access and ignore errors so this is safe in environments where
91125
89743
  // the EditorWorker / ListenerType are not available (e.g. unit tests).
91126
- const EditorChange = 1;
91127
- const rpcId = 9112;
91128
- try {
91129
- await invoke$1('Listener.register', EditorChange, rpcId);
91130
- } catch (error) {
91131
- console.error(error);
91132
- }
91133
89744
 
91134
89745
  // Read and parse file contents if we have a URI
91135
89746
  const {
91136
- content,
91137
- css,
91138
- errorMessage,
91139
- parsedDom,
91140
- parsedNodesChildNodeCount,
91141
- scripts
91142
- } = state.uri ? await updateContent(state, state.uri) : {
91143
- content: state.content,
91144
- css: state.css,
91145
- errorMessage: state.errorMessage,
91146
- parsedDom: state.parsedDom,
91147
- parsedNodesChildNodeCount: state.parsedNodesChildNodeCount,
91148
- scripts: state.scripts
91149
- };
91150
- const {
91151
- sandboxRpc
91152
- } = state;
91153
- let finalParsedDom = parsedDom;
91154
- let finalCss = css;
91155
- let finalParsedNodesChildNodeCount = parsedNodesChildNodeCount;
91156
- if (state.useSandboxWorker && scripts.length > 0) {
91157
- await sandboxRpc.invoke('SandBox.initialize', state.uid, content, scripts);
91158
- const serialized = await sandboxRpc.invoke('SandBox.getSerializedDom', state.uid);
91159
- finalParsedDom = serialized.dom;
91160
- finalCss = serialized.css;
91161
- finalParsedNodesChildNodeCount = finalParsedDom.length > 0 ? finalParsedDom[0].childCount || 0 : 0;
91162
- }
91163
- return {
91164
- ...state,
91165
- content,
91166
- css: finalCss,
91167
- errorCount: 0,
91168
- errorMessage,
91169
- initial: false,
91170
- parsedDom: finalParsedDom,
91171
- parsedNodesChildNodeCount: finalParsedNodesChildNodeCount,
91172
- sandboxRpc,
91173
- scripts,
91174
- warningCount: 1
91175
- };
91176
- };
91177
-
91178
- const BODY_SELECTOR_REGEX = /\bbody\b/g;
91179
- const HTML_SELECTOR_REGEX = /\bhtml\b/g;
91180
-
91181
- /**
91182
- * Wraps CSS in a CSS nesting block (.Preview { ... }) and replaces 'html' and 'body'
91183
- * selectors with '&' (the parent selector in CSS nesting).
91184
- * This approach uses CSS nesting to automatically scope all selectors to the preview div.
91185
- * Other selectors like 'button' or '*' are automatically scoped within the nesting.
91186
- *
91187
- * @param css The CSS string to process
91188
- * @returns The CSS string wrapped in .Preview nesting block with proper selector replacements
91189
- */
91190
- const replaceCssBodySelector = css => {
91191
- if (!css.trim()) {
91192
- return css;
91193
- }
91194
-
91195
- // Replace 'html' selector with '&' (CSS nesting parent selector)
91196
- let result = css.replaceAll(HTML_SELECTOR_REGEX, '&');
91197
-
91198
- // Replace 'body' selector with '&' (CSS nesting parent selector)
91199
- result = result.replaceAll(BODY_SELECTOR_REGEX, '&');
91200
-
91201
- // Wrap the entire CSS in .Preview nesting block
91202
- result = `.Preview {\n${result}\n}`;
91203
- return result;
91204
- };
91205
-
91206
- const renderCss = (oldState, newState) => {
91207
- const {
91208
- css,
91209
- uid
91210
- } = newState;
91211
-
91212
- // Combine all CSS strings into a single string
91213
- let cssString = css.join('\n');
91214
-
91215
- // Replace body selector with .Preview since we render the preview in a div element, not a body
91216
- cssString = replaceCssBodySelector(cssString);
91217
-
91218
- // Return command in format that can be handled by the viewlet
91219
- // The 'Viewlet.setCss' is a method that should be called on the viewlet
91220
- return ['Viewlet.setCss', uid, cssString];
91221
- };
91222
-
91223
- const HandleInput = 4;
91224
- const HandleClick = 11;
91225
- const HandleKeydown = 12;
91226
- const HandleKeyup = 13;
91227
- const HandleMousedown = 14;
91228
- const HandleMousemove = 15;
91229
- const HandleMouseup = 16;
91230
-
91231
- const getEmptyPreviewDom = () => {
91232
- return [{
91233
- childCount: 1,
91234
- className: 'Viewlet Preview',
91235
- type: Div$1
91236
- }, {
91237
- childCount: 1,
91238
- type: H1$1
91239
- }, {
91240
- text: 'No URI has been specified',
91241
- type: Text$2
91242
- }];
91243
- };
91244
-
91245
- const getPreviewDom = state => {
91246
- const {
91247
- parsedDom,
91248
- parsedNodesChildNodeCount,
91249
- uri
91250
- } = state;
91251
- if (!uri) {
91252
- return getEmptyPreviewDom();
91253
- }
91254
-
91255
- // If parsedDom is available, render it as children of the wrapper
91256
- if (parsedDom && parsedDom.length > 0) {
91257
- return [{
91258
- childCount: parsedNodesChildNodeCount,
91259
- className: 'Viewlet Preview',
91260
- onClick: HandleClick,
91261
- onInput: HandleInput,
91262
- onKeyDown: HandleKeydown,
91263
- onKeyUp: HandleKeyup,
91264
- onMouseDown: HandleMousedown,
91265
- onMouseMove: HandleMousemove,
91266
- onMouseUp: HandleMouseup,
91267
- tabIndex: 0,
91268
- type: Div$1
91269
- }, ...parsedDom];
91270
- }
91271
- return [{
91272
- childCount: 1,
91273
- className: 'Viewlet Preview',
91274
- onClick: HandleClick,
91275
- onInput: HandleInput,
91276
- onKeyDown: HandleKeydown,
91277
- onKeyUp: HandleKeyup,
91278
- onMouseDown: HandleMousedown,
91279
- onMouseMove: HandleMousemove,
91280
- onMouseUp: HandleMouseup,
91281
- tabIndex: 0,
91282
- type: Div$1
91283
- }, {
91284
- childCount: 1,
91285
- type: H1$1
91286
- }, {
91287
- text: 'Edit the file on the left to get started.',
91288
- type: Text$2
91289
- }];
91290
- };
91291
-
91292
- const renderItems = (oldState, newState) => {
91293
- const {
91294
- initial,
91295
- uid
91296
- } = newState;
91297
- if (initial) {
91298
- return [SetDom2, uid, []];
91299
- }
91300
- const dom = getPreviewDom(newState);
91301
- return [SetDom2, uid, dom];
91302
- };
91303
-
91304
- const renderIncremental = (oldState, newState) => {
91305
- const oldDom = renderItems(oldState, oldState)[2];
91306
- const newDom = renderItems(newState, newState)[2];
91307
- const patches = diffTree(oldDom, newDom);
91308
- return [SetPatches, newState.uid, patches];
91309
- };
91310
-
91311
- const getRenderer = diffType => {
91312
- switch (diffType) {
91313
- case RenderCss:
91314
- return renderCss;
91315
- case RenderIncremental:
91316
- return renderIncremental;
91317
- case RenderItems:
91318
- return renderItems;
91319
- default:
91320
- throw new Error('unknown renderer');
91321
- }
91322
- };
91323
-
91324
- const applyRender = (oldState, newState, diffResult) => {
91325
- const commands = [];
91326
- for (const item of diffResult) {
91327
- const fn = getRenderer(item);
91328
- const result = fn(oldState, newState);
91329
- if (result.length > 0) {
91330
- commands.push(result);
91331
- }
91332
- }
91333
- return commands;
91334
- };
91335
-
91336
- const render2 = (uid, diffResult) => {
91337
- const {
91338
- newState,
91339
- oldState
91340
- } = get$1(uid);
91341
- set$2(uid, newState, newState);
91342
- const commands = applyRender(oldState, newState, diffResult);
91343
- return commands;
91344
- };
91345
-
91346
- const rerender = state => {
91347
- // Create a new copy of parsedDom array to trigger diff
91348
- const parsedDom = [...state.parsedDom];
91349
-
91350
- // Return a new state object with the copied parsedDom
91351
- // This will cause DiffItems.isEqual to return false since parsedDom reference changed
89747
+ errorMessage
89748
+ } = await updateContent(uid, width, height, content, scripts);
91352
89749
  return {
91353
- ...state,
91354
- parsedDom
89750
+ errorMessage
91355
89751
  };
91356
89752
  };
91357
89753
 
@@ -91363,36 +89759,26 @@ const resize = (state, dimensions) => {
91363
89759
  };
91364
89760
 
91365
89761
  const commandMap = {
91366
- 'PreviewSandBox.create': create,
91367
- 'PreviewSandBox.diff2': diff2,
91368
- 'PreviewSandBox.executeCallback': executeCallback,
91369
- 'PreviewSandBox.handleClick': wrapCommand(handleClick),
91370
- 'PreviewSandBox.handleFileEdited': wrapCommand(handleFileEdited),
91371
- 'PreviewSandBox.handleInput': wrapCommand(handleInput),
91372
- 'PreviewSandBox.handleKeyDown': wrapCommand(handleKeydown),
91373
- 'PreviewSandBox.handleKeyUp': wrapCommand(handleKeyup),
91374
- 'PreviewSandBox.handleMessagePort': handleMessagePort,
91375
- 'PreviewSandBox.handleMousedown': wrapCommand(handleMousedown),
91376
- 'PreviewSandBox.handleMousemove': wrapCommand(handleMousemove),
91377
- 'PreviewSandBox.handleMouseup': wrapCommand(handleMouseup),
91378
- 'PreviewSandBox.loadContent': wrapCommand(loadContent),
91379
- 'PreviewSandBox.render2': render2,
91380
- 'PreviewSandBox.rerender': wrapCommand(rerender),
91381
- 'PreviewSandBox.resize': wrapCommand(resize),
91382
- 'PreviewSandBox.terminate': terminate
89762
+ 'SandBox.executeCallback': executeCallback,
89763
+ 'SandBox.getSerializedDom': getSerializedDom,
89764
+ 'SandBox.handleClick': handleClick,
89765
+ 'SandBox.handleInput': handleInput,
89766
+ 'SandBox.handleKeyDown': handleKeydown,
89767
+ 'SandBox.handleKeyUp': handleKeyup,
89768
+ 'SandBox.handleMessagePort': handleMessagePort,
89769
+ 'SandBox.handleMousedown': handleMousedown,
89770
+ 'SandBox.handleMousemove': handleMousemove,
89771
+ 'SandBox.handleMouseup': handleMouseup,
89772
+ 'SandBox.loadContent': loadContent,
89773
+ 'SandBox.resize': resize,
89774
+ 'SandBox.terminate': terminate
91383
89775
  };
91384
89776
 
91385
89777
  const listen = async () => {
91386
- registerCommands(commandMap);
91387
89778
  const rpc = await WebWorkerRpcClient.create({
91388
89779
  commandMap: commandMap
91389
89780
  });
91390
- set$3(rpc);
91391
- const editorRpc = await LazyTransferMessagePortRpcParent.create({
91392
- commandMap: {},
91393
- send: port => sendMessagePortToEditorWorker(port, 9112)
91394
- });
91395
- set$4(editorRpc);
89781
+ set$2(rpc);
91396
89782
  };
91397
89783
 
91398
89784
  const main = async () => {