code wiki / _hdl_build / nx_js_render_gate.nx

nx_js_render_gate.nx source

↩ module page · 78 lines · 4961 B

1// nx_js_render_gate.nx -- gate for R-JS-DOMWRITE: the sovereign JS engine now BUILDS rendered content. 2// Drives js_render_page (parse->tree, run inline scripts in tree mode, serialize). Proves DOM-write 3// (getElementById().innerHTML= / .textContent=) actually mutates what renders. 0=GREEN/1=RED. 4import "nx_syscalls.nx" 5import "nx_js_eval.nx" 6 7func r_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 8func r_pn(v: i64) -> i64 { 9 var m: i64 = v 10 if m < 0 { r_p("-\x00" as *u8); m = 0 - m } 11 let t: *u8 = sys_mmap(24); var k: i64 = 0 12 if m == 0 { t[0] = 48 as u8; k = 1 } else { while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } } 13 let o: *u8 = sys_mmap(24); var j: i64 = 0 14 while j < k { o[j] = t[k - 1 - j]; j = j + 1 } 15 sys_write(1, o, k); return 0 16} 17func r_clen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 18func r_contains(buf: *u8, blen: i64, needle: *u8) -> i64 { 19 let nl: i64 = r_clen(needle) 20 if nl == 0 { return 1 } 21 var i: i64 = 0 22 while (i + nl) <= blen { 23 var j: i64 = 0; var ok: i64 = 1 24 while j < nl { if (buf[i + j] & 0xff) != (needle[j] & 0xff) { ok = 0; j = nl } else { j = j + 1 } } 25 if ok == 1 { return 1 } 26 i = i + 1 27 } 28 return 0 29} 30func chk(cond: i64, name: *u8, pp: *i64, tp: *i64) -> i64 { 31 tp[0] = tp[0] + 1; r_p(name) 32 if cond == 1 { pp[0] = pp[0] + 1; r_p(" ok\n\x00" as *u8) } else { r_p(" FAIL\n\x00" as *u8) } 33 return 0 34} 35 36func main() -> i64 { 37 let pp: *i64 = sys_mmap(8) as *i64; pp[0] = 0 38 let tp: *i64 = sys_mmap(8) as *i64; tp[0] = 0 39 let out: *u8 = sys_mmap(131072) 40 41 // R1: a script BUILDS content via innerHTML -> renders into the serialized DOM (the core win) 42 let page1: *u8 = "<html><body><div id=\"app\">old</div><script>document.getElementById('app').innerHTML='<p>built by JS</p>';</script></body></html>\x00" as *u8 43 let n1: i64 = js_render_page(page1, r_clen(page1), out, 131072) 44 chk(r_contains(out, n1, "<p>built by JS</p>\x00" as *u8), "R1 innerHTML builds DOM\x00" as *u8, pp, tp) 45 chk(r_contains(out, n1, ">old<\x00" as *u8) == 0, "R1b old content replaced\x00" as *u8, pp, tp) 46 47 // R2: textContent= mutation renders 48 let page2: *u8 = "<html><body><span id=\"s\">x</span><script>document.getElementById('s').textContent='ZZZ';</script></body></html>\x00" as *u8 49 let n2: i64 = js_render_page(page2, r_clen(page2), out, 131072) 50 chk(r_contains(out, n2, "ZZZ\x00" as *u8), "R2 textContent= renders\x00" as *u8, pp, tp) 51 52 // R3: no-script page still round-trips unchanged (control) 53 let page3: *u8 = "<html><body><h1>Hello</h1></body></html>\x00" as *u8 54 let n3: i64 = js_render_page(page3, r_clen(page3), out, 131072) 55 chk(r_contains(out, n3, "<h1>Hello</h1>\x00" as *u8), "R3 no-script round-trip\x00" as *u8, pp, tp) 56 57 // R4: missing-id getElementById is null -> assigning throws inside script, page unharmed (neg control) 58 let page4: *u8 = "<html><body><div id=\"keep\">stay</div><script>var e=document.getElementById('absent'); if(e){ e.textContent='X'; }</script></body></html>\x00" as *u8 59 let n4: i64 = js_render_page(page4, r_clen(page4), out, 131072) 60 chk(r_contains(out, n4, "stay\x00" as *u8), "R4 missing-id safe\x00" as *u8, pp, tp) 61 62 // R5: a script BUILDS a node via createElement + setAttribute + appendChild (the React-style pattern) 63 let page5: *u8 = "<html><body><div id=\"box\"></div><script>var d=document.createElement('p');d.textContent='made by createElement';d.setAttribute('class','built');document.getElementById('box').appendChild(d);</script></body></html>\x00" as *u8 64 let n5: i64 = js_render_page(page5, r_clen(page5), out, 131072) 65 chk(r_contains(out, n5, "made by createElement\x00" as *u8), "R5 createElement+appendChild builds\x00" as *u8, pp, tp) 66 chk(r_contains(out, n5, "class=\"built\"\x00" as *u8), "R5b setAttribute on built node\x00" as *u8, pp, tp) 67 68 // R6: querySelectorAll('.class').length + querySelector('tag').setAttribute, rendered 69 let page6: *u8 = "<html><body><ul><li class=\"it\">A</li><li class=\"it\">B</li><li>C</li></ul><div id=\"out\"></div><script>var n=document.querySelectorAll('.it').length;document.getElementById('out').textContent='count='+n;document.querySelector('li').setAttribute('data-first','yes');</script></body></html>\x00" as *u8 70 let n6: i64 = js_render_page(page6, r_clen(page6), out, 131072) 71 chk(r_contains(out, n6, "count=2\x00" as *u8), "R6 querySelectorAll .length\x00" as *u8, pp, tp) 72 chk(r_contains(out, n6, "data-first=\"yes\"\x00" as *u8), "R6b querySelector+setAttribute\x00" as *u8, pp, tp) 73 74 r_p("JSRENDERGATE pass=\x00" as *u8); r_pn(pp[0]); r_p("/\x00" as *u8); r_pn(tp[0]); r_p("\n\x00" as *u8) 75 if pp[0] == tp[0] { r_p("JSRENDERGATE verdict=GREEN\n\x00" as *u8); return 0 } 76 r_p("JSRENDERGATE verdict=RED\n\x00" as *u8) 77 return 1 78}