template.html 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. <!-- a js-only interpreter for the dioxus patch stream :) -->
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
  6. <meta charset="UTF-8" />
  7. <link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet" />
  8. </head>
  9. <body>
  10. <div>hello dioxus</div>
  11. </body>
  12. <script>
  13. class Interpreter {
  14. constructor(root) {
  15. this.stack = [root];
  16. }
  17. top() {
  18. return this.stack[this.stack.length - 1];
  19. }
  20. pop() {
  21. return this.stack.pop();
  22. }
  23. }
  24. class OPTABLE {
  25. // 0
  26. SetText(edit, interp) {
  27. interp.top(interp.stack).textContent = edit.text;
  28. }
  29. // 1
  30. RemoveSelfAndNextSiblings(edit) {
  31. const node = interp.pop();
  32. let sibling = node.nextSibling;
  33. while (sibling) {
  34. const temp = sibling.nextSibling;
  35. sibling.remove();
  36. sibling = temp;
  37. }
  38. node.remove();
  39. }
  40. // 2
  41. ReplaceWith(edit, interp) {
  42. const newNode = interp.pop();
  43. const oldNode = interp.pop();
  44. oldNode.replaceWith(newNode);
  45. interp.stack.push(newNode);
  46. }
  47. // 3
  48. SetAttribute(edit, interp) {
  49. const name = edit.name;
  50. const value = edit.value;
  51. const node = interp.top(interp.stack);
  52. node.setAttribute(name, value);
  53. // Some attributes are "volatile" and don't work through `setAttribute`.
  54. if ((name === "value", interp)) {
  55. node.value = value;
  56. }
  57. if ((name === "checked", interp)) {
  58. node.checked = true;
  59. }
  60. if ((name === "selected", interp)) {
  61. node.selected = true;
  62. }
  63. }
  64. // 4
  65. RemoveAttribute(edit, interp) {
  66. const name = edit.name;
  67. const node = interp.top(interp.stack);
  68. node.removeAttribute(name);
  69. // Some attributes are "volatile" and don't work through `removeAttribute`.
  70. if ((name === "value", interp)) {
  71. node.value = null;
  72. }
  73. if ((name === "checked", interp)) {
  74. node.checked = false;
  75. }
  76. if ((name === "selected", interp)) {
  77. node.selected = false;
  78. }
  79. }
  80. // 5
  81. PushReverseChild(edit, interp) {
  82. const n = edit.n;
  83. const parent = interp.top(interp.stack);
  84. const children = parent.childNodes;
  85. const child = children[children.length - n - 1];
  86. interp.stack.push(child);
  87. }
  88. // 6
  89. PopPushChild(edit, interp) {
  90. const n = edit.n;
  91. interp.pop();
  92. const parent = interp.top(interp.stack);
  93. const children = parent.childNodes;
  94. const child = children[n];
  95. interp.stack.push(child);
  96. }
  97. // 7
  98. Pop(edit, interp) {
  99. interp.pop();
  100. }
  101. // 8
  102. AppendChild(edit, interp) {
  103. console.log(interp.stack);
  104. const child = interp.pop();
  105. console.log(interp.stack);
  106. interp.top().appendChild(child);
  107. }
  108. // 9
  109. CreateTextNode(edit, interp) {
  110. // interp.stack.push(document.createTextNode("asd"));
  111. console.log(interp.stack);
  112. interp.stack.push(document.createTextNode(edit.text));
  113. console.log(interp.stack);
  114. }
  115. // 10
  116. CreateElement(edit, interp) {
  117. const tagName = edit.tag_name;
  118. interp.stack.push(document.createElement(tagName));
  119. }
  120. // 11
  121. NewEventListener(edit, interp) {
  122. // todo!
  123. const eventId = mem32[i++];
  124. const eventType = interp.getCachedString(eventId);
  125. const a = mem32[i++];
  126. const b = mem32[i++];
  127. const el = interp.top(interp.stack);
  128. el.addEventListener(eventType, interp.eventHandler);
  129. el[`dodrio-a-${eventType}`] = a;
  130. el[`dodrio-b-${eventType}`] = b;
  131. }
  132. // 12
  133. UpdateEventListener(edit, interp) {
  134. // todo!
  135. const eventId = mem32[i++];
  136. const eventType = interp.getCachedString(eventId);
  137. const el = interp.top(interp.stack);
  138. el[`dodrio-a-${eventType}`] = mem32[i++];
  139. el[`dodrio-b-${eventType}`] = mem32[i++];
  140. }
  141. // 13
  142. RemoveEventListener(edit, interp) {
  143. // todo!
  144. const eventId = mem32[i++];
  145. const eventType = interp.getCachedString(eventId);
  146. const el = interp.top(interp.stack);
  147. el.removeEventListener(eventType, interp.eventHandler);
  148. }
  149. // 14
  150. AddCachedString(edit, interp) {
  151. // todo!
  152. const pointer = mem32[i++];
  153. const length = mem32[i++];
  154. const id = mem32[i++];
  155. const str = string(mem8, pointer, length);
  156. interp.addCachedString(str, id);
  157. }
  158. // 15
  159. DropCachedString(edit, interp) {
  160. // todo!
  161. const id = mem32[i++];
  162. interp.dropCachedString(id);
  163. }
  164. // 16
  165. CreateElementNS(edit, interp) {
  166. // const tagNameId = mem32[i++];
  167. // const tagName = interp.getCachedString(tagNameId);
  168. // const nsId = mem32[i++];
  169. // const ns = interp.getCachedString(nsId);
  170. interp.stack.push(document.createElementNS(edit.ns, edit.tag_name));
  171. }
  172. // 17
  173. SaveChildrenToTemporaries(edit, interp) {
  174. // let temp = mem32[i++];
  175. // const start = mem32[i++];
  176. // const end = mem32[i++];
  177. let temp = edit.temp;
  178. const start = edit.start;
  179. const end = edit.end;
  180. const parent = interp.top(interp.stack);
  181. const children = parent.childNodes;
  182. for (let i = start; i < end; i++, interp) {
  183. interp.temporaries[temp++] = children[i];
  184. }
  185. }
  186. // 18
  187. PushChild(edit, interp) {
  188. const parent = interp.top(interp.stack);
  189. // const n = mem32[i++];
  190. const n = edit.n;
  191. const child = parent.childNodes[n];
  192. interp.stack.push(child);
  193. }
  194. // 19
  195. PushTemporary(edit, interp) {
  196. // const temp = mem32[i++];
  197. const temp = edit.temp;
  198. interp.stack.push(interp.temporaries[temp]);
  199. }
  200. // 20
  201. InsertBefore(edit, interp) {
  202. const before = interp.pop();
  203. const after = interp.pop();
  204. after.parentNode.insertBefore(before, after);
  205. interp.stack.push(before);
  206. }
  207. // 21
  208. PopPushReverseChild(edit, interp) {
  209. // const n = mem32[i++];
  210. const n = edit.n;
  211. interp.pop();
  212. const parent = interp.top(interp.stack);
  213. const children = parent.childNodes;
  214. const child = children[children.length - n - 1];
  215. interp.stack.push(child);
  216. }
  217. // 22
  218. RemoveChild(edit, interp) {
  219. // const n = mem32[i++];
  220. const n = edit.n;
  221. const parent = interp.top(interp.stack);
  222. const child = parent.childNodes[n];
  223. child.remove();
  224. }
  225. // 23
  226. SetClass(edit, interp) {
  227. // const classId = mem32[i++];
  228. const className = edit.class_name;
  229. interp.top(interp.stack).className = className;
  230. }
  231. // 24
  232. SaveTemplate(edit, interp) {
  233. const id = mem32[i++];
  234. const template = interp.top(interp.stack);
  235. interp.saveTemplate(id, template.cloneNode(true));
  236. }
  237. // 25
  238. PushTemplate(edit, interp) {
  239. const id = mem32[i++];
  240. const template = interp.getTemplate(id);
  241. interp.stack.push(template.cloneNode(true));
  242. }
  243. NewListener(edit, interp) {}
  244. }
  245. const op_table = new OPTABLE();
  246. const interpreter = new Interpreter(window.document.body);
  247. function EditListReceived(rawEditList) {
  248. let editList = JSON.parse(rawEditList);
  249. editList.forEach(function (edit, index) {
  250. op_table[edit.type](edit, interpreter);
  251. });
  252. }
  253. let socket = new WebSocket("ws://127.0.0.1:8080/session/itsworkinggg");
  254. socket.onmessage = function(event) {
  255. console.log(event.data);
  256. EditListReceived(event.data);
  257. }
  258. // external.invoke("initiate");
  259. </script>
  260. </html>