index.html 7.7 KB

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