interpreter.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. "use strict";
  2. var exports = {};
  3. exports.__esModule = true;
  4. exports.Interpreter = void 0;
  5. function serialize_event(event) {
  6. var _a, _b;
  7. switch (event.type) {
  8. case "copy":
  9. case "cut":
  10. case "past":
  11. return {};
  12. case "compositionend":
  13. case "compositionstart":
  14. case "compositionupdate":
  15. var data = event.data;
  16. return {
  17. data: data,
  18. };
  19. case "keydown":
  20. case "keypress":
  21. case "keyup":
  22. var _c = event,
  23. charCode = _c.charCode,
  24. key = _c.key,
  25. altKey = _c.altKey,
  26. ctrlKey = _c.ctrlKey,
  27. metaKey = _c.metaKey,
  28. keyCode = _c.keyCode,
  29. shiftKey = _c.shiftKey,
  30. location_1 = _c.location,
  31. repeat = _c.repeat,
  32. which = _c.which;
  33. return {
  34. char_code: charCode,
  35. key: key,
  36. alt_key: altKey,
  37. ctrl_key: ctrlKey,
  38. meta_key: metaKey,
  39. key_code: keyCode,
  40. shift_key: shiftKey,
  41. location: location_1,
  42. repeat: repeat,
  43. which: which,
  44. locale: "locale",
  45. };
  46. case "focus":
  47. case "blur":
  48. return {};
  49. case "change":
  50. var target = event.target;
  51. var value = void 0;
  52. if (target.type === "checkbox" || target.type === "radio") {
  53. value = target.checked ? "true" : "false";
  54. } else {
  55. value =
  56. (_a = target.value) !== null && _a !== void 0
  57. ? _a
  58. : target.textContent;
  59. }
  60. return {
  61. value: value,
  62. };
  63. case "input":
  64. case "invalid":
  65. case "reset":
  66. case "submit": {
  67. var target_1 = event.target;
  68. var value_1 =
  69. (_b = target_1.value) !== null && _b !== void 0
  70. ? _b
  71. : target_1.textContent;
  72. if (target_1.type == "checkbox") {
  73. value_1 = target_1.checked ? "true" : "false";
  74. }
  75. return {
  76. value: value_1,
  77. };
  78. }
  79. case "click":
  80. case "contextmenu":
  81. case "doubleclick":
  82. case "drag":
  83. case "dragend":
  84. case "dragenter":
  85. case "dragexit":
  86. case "dragleave":
  87. case "dragover":
  88. case "dragstart":
  89. case "drop":
  90. case "mousedown":
  91. case "mouseenter":
  92. case "mouseleave":
  93. case "mousemove":
  94. case "mouseout":
  95. case "mouseover":
  96. case "mouseup": {
  97. var _d = event,
  98. altKey_1 = _d.altKey,
  99. button = _d.button,
  100. buttons = _d.buttons,
  101. clientX = _d.clientX,
  102. clientY = _d.clientY,
  103. ctrlKey_1 = _d.ctrlKey,
  104. metaKey_1 = _d.metaKey,
  105. pageX = _d.pageX,
  106. pageY = _d.pageY,
  107. screenX_1 = _d.screenX,
  108. screenY_1 = _d.screenY,
  109. shiftKey_1 = _d.shiftKey;
  110. return {
  111. alt_key: altKey_1,
  112. button: button,
  113. buttons: buttons,
  114. client_x: clientX,
  115. client_y: clientY,
  116. ctrl_key: ctrlKey_1,
  117. meta_key: metaKey_1,
  118. page_x: pageX,
  119. page_y: pageY,
  120. screen_x: screenX_1,
  121. screen_y: screenY_1,
  122. shift_key: shiftKey_1,
  123. };
  124. }
  125. case "pointerdown":
  126. case "pointermove":
  127. case "pointerup":
  128. case "pointercancel":
  129. case "gotpointercapture":
  130. case "lostpointercapture":
  131. case "pointerenter":
  132. case "pointerleave":
  133. case "pointerover":
  134. case "pointerout": {
  135. var _e = event,
  136. altKey_2 = _e.altKey,
  137. button = _e.button,
  138. buttons = _e.buttons,
  139. clientX = _e.clientX,
  140. clientY = _e.clientY,
  141. ctrlKey_2 = _e.ctrlKey,
  142. metaKey_2 = _e.metaKey,
  143. pageX = _e.pageX,
  144. pageY = _e.pageY,
  145. screenX_2 = _e.screenX,
  146. screenY_2 = _e.screenY,
  147. shiftKey_2 = _e.shiftKey,
  148. pointerId = _e.pointerId,
  149. width = _e.width,
  150. height = _e.height,
  151. pressure = _e.pressure,
  152. tangentialPressure = _e.tangentialPressure,
  153. tiltX = _e.tiltX,
  154. tiltY = _e.tiltY,
  155. twist = _e.twist,
  156. pointerType = _e.pointerType,
  157. isPrimary = _e.isPrimary;
  158. return {
  159. alt_key: altKey_2,
  160. button: button,
  161. buttons: buttons,
  162. client_x: clientX,
  163. client_y: clientY,
  164. ctrl_key: ctrlKey_2,
  165. meta_key: metaKey_2,
  166. page_x: pageX,
  167. page_y: pageY,
  168. screen_x: screenX_2,
  169. screen_y: screenY_2,
  170. shift_key: shiftKey_2,
  171. pointer_id: pointerId,
  172. width: width,
  173. height: height,
  174. pressure: pressure,
  175. tangential_pressure: tangentialPressure,
  176. tilt_x: tiltX,
  177. tilt_y: tiltY,
  178. twist: twist,
  179. pointer_type: pointerType,
  180. is_primary: isPrimary,
  181. };
  182. }
  183. case "select":
  184. return {};
  185. case "touchcancel":
  186. case "touchend":
  187. case "touchmove":
  188. case "touchstart": {
  189. var _f = event,
  190. altKey_3 = _f.altKey,
  191. ctrlKey_3 = _f.ctrlKey,
  192. metaKey_3 = _f.metaKey,
  193. shiftKey_3 = _f.shiftKey;
  194. return {
  195. // changed_touches: event.changedTouches,
  196. // target_touches: event.targetTouches,
  197. // touches: event.touches,
  198. alt_key: altKey_3,
  199. ctrl_key: ctrlKey_3,
  200. meta_key: metaKey_3,
  201. shift_key: shiftKey_3,
  202. };
  203. }
  204. case "scroll":
  205. return {};
  206. case "wheel": {
  207. var _g = event,
  208. deltaX = _g.deltaX,
  209. deltaY = _g.deltaY,
  210. deltaZ = _g.deltaZ,
  211. deltaMode = _g.deltaMode;
  212. return {
  213. delta_x: deltaX,
  214. delta_y: deltaY,
  215. delta_z: deltaZ,
  216. delta_mode: deltaMode,
  217. };
  218. }
  219. case "animationstart":
  220. case "animationend":
  221. case "animationiteration": {
  222. var _h = event,
  223. animationName = _h.animationName,
  224. elapsedTime = _h.elapsedTime,
  225. pseudoElement = _h.pseudoElement;
  226. return {
  227. animation_name: animationName,
  228. elapsed_time: elapsedTime,
  229. pseudo_element: pseudoElement,
  230. };
  231. }
  232. case "transitionend": {
  233. var _j = event,
  234. propertyName = _j.propertyName,
  235. elapsedTime = _j.elapsedTime,
  236. pseudoElement = _j.pseudoElement;
  237. return {
  238. property_name: propertyName,
  239. elapsed_time: elapsedTime,
  240. pseudo_element: pseudoElement,
  241. };
  242. }
  243. case "abort":
  244. case "canplay":
  245. case "canplaythrough":
  246. case "durationchange":
  247. case "emptied":
  248. case "encrypted":
  249. case "ended":
  250. case "error":
  251. case "loadeddata":
  252. case "loadedmetadata":
  253. case "loadstart":
  254. case "pause":
  255. case "play":
  256. case "playing":
  257. case "progress":
  258. case "ratechange":
  259. case "seeked":
  260. case "seeking":
  261. case "stalled":
  262. case "suspend":
  263. case "timeupdate":
  264. case "volumechange":
  265. case "waiting":
  266. return {};
  267. case "toggle":
  268. return {};
  269. default:
  270. return {};
  271. }
  272. }
  273. var bool_attrs = {
  274. allowfullscreen: true,
  275. allowpaymentrequest: true,
  276. async: true,
  277. autofocus: true,
  278. autoplay: true,
  279. checked: true,
  280. controls: true,
  281. default: true,
  282. defer: true,
  283. disabled: true,
  284. formnovalidate: true,
  285. hidden: true,
  286. ismap: true,
  287. itemscope: true,
  288. loop: true,
  289. multiple: true,
  290. muted: true,
  291. nomodule: true,
  292. novalidate: true,
  293. open: true,
  294. playsinline: true,
  295. readonly: true,
  296. required: true,
  297. reversed: true,
  298. selected: true,
  299. truespeed: true,
  300. };
  301. export var Interpreter = /** @class */ (function () {
  302. function Interpreter(root) {
  303. this.root = root;
  304. this.stack = [root];
  305. this.listeners = {};
  306. this.lastNodeWasText = false;
  307. this.nodes = [root];
  308. }
  309. Interpreter.prototype.top = function () {
  310. return this.stack[this.stack.length - 1];
  311. };
  312. Interpreter.prototype.pop = function () {
  313. return this.stack.pop();
  314. };
  315. Interpreter.prototype.PushRoot = function (root) {
  316. var node = this.nodes[root];
  317. this.stack.push(node);
  318. };
  319. Interpreter.prototype.AppendChildren = function (many) {
  320. var root = this.stack[this.stack.length - (1 + many)];
  321. var to_add = this.stack.splice(this.stack.length - many);
  322. for (var i = 0; i < many; i++) {
  323. root.appendChild(to_add[i]);
  324. }
  325. };
  326. Interpreter.prototype.ReplaceWith = function (root_id, m) {
  327. var root = this.nodes[root_id];
  328. var els = this.stack.splice(this.stack.length - m);
  329. root.replaceWith.apply(root, els);
  330. };
  331. Interpreter.prototype.InsertAfter = function (root, n) {
  332. var old = this.nodes[root];
  333. var new_nodes = this.stack.splice(this.stack.length - n);
  334. old.after.apply(old, new_nodes);
  335. };
  336. Interpreter.prototype.InsertBefore = function (root, n) {
  337. var old = this.nodes[root];
  338. var new_nodes = this.stack.splice(this.stack.length - n);
  339. old.before.apply(old, new_nodes);
  340. };
  341. Interpreter.prototype.Remove = function (root) {
  342. var node = this.nodes[root];
  343. if (node !== undefined) {
  344. node.remove();
  345. }
  346. };
  347. Interpreter.prototype.CreateTextNode = function (text, root) {
  348. // todo: make it so the types are okay
  349. var node = document.createTextNode(text);
  350. this.nodes[root] = node;
  351. this.stack.push(node);
  352. };
  353. Interpreter.prototype.CreateElement = function (tag, root) {
  354. var el = document.createElement(tag);
  355. el.setAttribute("dioxus-id", "".concat(root));
  356. this.nodes[root] = el;
  357. this.stack.push(el);
  358. };
  359. Interpreter.prototype.CreateElementNs = function (tag, root, ns) {
  360. var el = document.createElementNS(ns, tag);
  361. this.stack.push(el);
  362. this.nodes[root] = el;
  363. };
  364. Interpreter.prototype.CreatePlaceholder = function (root) {
  365. var el = document.createElement("pre");
  366. el.hidden = true;
  367. this.stack.push(el);
  368. this.nodes[root] = el;
  369. };
  370. Interpreter.prototype.NewEventListener = function (event_name, scope, root) {
  371. console.log("new event listener", event_name, root, scope);
  372. var element = this.nodes[root];
  373. element.setAttribute(
  374. "dioxus-event-".concat(event_name),
  375. "".concat(scope, ".").concat(root)
  376. );
  377. // if (!this.listeners[event_name]) {
  378. // this.listeners[event_name] = handler;
  379. // this.root.addEventListener(event_name, handler);
  380. // }
  381. };
  382. Interpreter.prototype.RemoveEventListener = function (
  383. root,
  384. event_name,
  385. scope
  386. ) {
  387. //
  388. };
  389. Interpreter.prototype.SetText = function (root, text) {
  390. this.nodes[root].textContent = text;
  391. };
  392. Interpreter.prototype.SetAttribute = function (root, field, value, ns) {
  393. var name = field;
  394. var node = this.nodes[root];
  395. if (ns == "style") {
  396. // @ts-ignore
  397. node.style[name] = value;
  398. } else if (ns != null || ns != undefined) {
  399. node.setAttributeNS(ns, name, value);
  400. } else {
  401. switch (name) {
  402. case "value":
  403. if (value != node.value) {
  404. node.value = value;
  405. }
  406. break;
  407. case "checked":
  408. node.checked = value === "true";
  409. break;
  410. case "selected":
  411. node.selected = value === "true";
  412. break;
  413. case "dangerous_inner_html":
  414. node.innerHTML = value;
  415. break;
  416. default:
  417. // https://github.com/facebook/react/blob/8b88ac2592c5f555f315f9440cbb665dd1e7457a/packages/react-dom/src/shared/DOMProperty.js#L352-L364
  418. if (value == "false" && bool_attrs.hasOwnProperty(name)) {
  419. node.removeAttribute(name);
  420. } else {
  421. node.setAttribute(name, value);
  422. }
  423. }
  424. }
  425. };
  426. Interpreter.prototype.RemoveAttribute = function (root, name) {
  427. var node = this.nodes[root];
  428. node.removeAttribute(name);
  429. if (name === "value") {
  430. node.value = "";
  431. }
  432. if (name === "checked") {
  433. node.checked = false;
  434. }
  435. if (name === "selected") {
  436. node.selected = false;
  437. }
  438. };
  439. Interpreter.prototype.handleEdits = function (edits) {
  440. console.log("handling edits ", edits);
  441. this.stack.push(this.root);
  442. for (var _i = 0, edits_1 = edits; _i < edits_1.length; _i++) {
  443. var edit = edits_1[_i];
  444. this.handleEdit(edit);
  445. }
  446. };
  447. Interpreter.prototype.handleEdit = function (edit) {
  448. switch (edit.type) {
  449. case "PushRoot":
  450. this.PushRoot(edit.root);
  451. break;
  452. case "AppendChildren":
  453. this.AppendChildren(edit.many);
  454. break;
  455. case "ReplaceWith":
  456. this.ReplaceWith(edit.root, edit.m);
  457. break;
  458. case "InsertAfter":
  459. this.InsertAfter(edit.root, edit.n);
  460. break;
  461. case "InsertBefore":
  462. this.InsertBefore(edit.root, edit.n);
  463. break;
  464. case "Remove":
  465. this.Remove(edit.root);
  466. break;
  467. case "CreateTextNode":
  468. this.CreateTextNode(edit.text, edit.root);
  469. break;
  470. case "CreateElement":
  471. this.CreateElement(edit.tag, edit.root);
  472. break;
  473. case "CreateElementNs":
  474. this.CreateElementNs(edit.tag, edit.root, edit.ns);
  475. break;
  476. case "CreatePlaceholder":
  477. this.CreatePlaceholder(edit.root);
  478. break;
  479. case "RemoveEventListener":
  480. this.RemoveEventListener(edit.root, edit.event_name, edit.scope);
  481. break;
  482. case "NewEventListener":
  483. // todo: only on desktop should we make our own handler
  484. var handler = function (event) {
  485. var target = event.target;
  486. console.log("event", event);
  487. if (target != null) {
  488. var real_id = target.getAttribute("dioxus-id");
  489. var should_prevent_default = target.getAttribute(
  490. "dioxus-prevent-default"
  491. );
  492. var contents = serialize_event(event);
  493. if (should_prevent_default === "on".concat(event.type)) {
  494. event.preventDefault();
  495. }
  496. if (real_id == null) {
  497. return;
  498. }
  499. window.rpc.call("user_event", {
  500. event: edit.event_name,
  501. mounted_dom_id: parseInt(real_id),
  502. contents: contents,
  503. });
  504. }
  505. };
  506. this.NewEventListener(edit.event_name, edit.scope, edit.root);
  507. // this.NewEventListener(edit, handler);
  508. break;
  509. case "SetText":
  510. this.SetText(edit.root, edit.text);
  511. break;
  512. case "SetAttribute":
  513. this.SetAttribute(edit.root, edit.field, edit.value, edit.ns);
  514. break;
  515. case "RemoveAttribute":
  516. this.RemoveAttribute(edit.root, edit.name);
  517. break;
  518. }
  519. };
  520. return Interpreter;
  521. })();
  522. exports.Interpreter = Interpreter;
  523. function main() {
  524. var root = window.document.getElementById("main");
  525. if (root != null) {
  526. window.interpreter = new Interpreter(root);
  527. window.rpc.call("initialize");
  528. }
  529. }