interpreter.js 15 KB

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