code wiki / _hdl_build / nx_browser_find_gate.nx
nx_browser_find_gate.nx source
↩ module page · 123 lines · 6669 B
1// nx_browser_find_gate.nx -- gate for FIND-IN-PAGE (the Ctrl+F feature every browser has; UX census had
2// it as an ADMITTED gap -- this flips it, with EVIDENCE). Proves on the real bench page through the real
3// core: (T1) the term "wizards" is FOUND with the right match count; (T2) the first-match page-y is
4// returned (scroll-to target) and really is the paragraph's y; (T3) with the find active the render shows
5// HIGHLIGHT pixels (#FFE066) under the match; (T4) with no find active there are ZERO highlight pixels;
6// (T5) NEG: an absent term matches 0 and highlights NOTHING (the highlighter cannot false-fire);
7// (T6) case-insensitive ("WIZARDS" == "wizards"); (T7) EVIDENCE CLIP recorded: page -> find+highlight ->
8// scrolled-to-match, browser-playable APNG (knowledge/status/usersim_find_clip.png).
9// expect_exit: 0 license_tier: ORIGINAL
10import "nx_browser_render.nx"
11import "nx_apng_write.nx"
12
13func fg_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
14func fg_num(v: i64) -> i64 { let b: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 }
15
16const FG_W: i64 = 500
17const FG_H: i64 = 400
18
19// render into a fresh RGBA buffer at scroll sy; returns pixels
20func fg_frame(page: *Page, sy: i64) -> *u8 {
21 let fb: *Framebuffer = sys_mmap(NX_FRAMEBUFFER_BYTES) as *Framebuffer
22 let px: *u8 = sys_mmap(FG_W*FG_H*4 + 64)
23 nx_framebuffer_init(fb, px, FG_W, FG_H)
24 br_draw_fb_at(fb, page, FG_W, "usersim://find\x00" as *u8, 14, 1, sy)
25 return px
26}
27// count highlight-yellow pixels (255,224,102)
28func fg_hl(px: *u8) -> i64 {
29 var cnt: i64 = 0
30 var i: i64 = 0
31 while i < FG_W*FG_H {
32 if (px[i*4] as i64)==255 { if (px[i*4+1] as i64)==224 { if (px[i*4+2] as i64)==102 { cnt=cnt+1 } } }
33 i = i + 1
34 }
35 return cnt
36}
37func fg_rgb(px: *u8, rgb: *u8) -> i64 {
38 var p: i64 = 0
39 while p < FG_W*FG_H { rgb[p*3]=px[p*4]; rgb[p*3+1]=px[p*4+1]; rgb[p*3+2]=px[p*4+2]; p=p+1 }
40 return 0
41}
42
43func main() -> i64 {
44 fg_puts("FIND-IN-PAGE gate: search -> highlight -> scroll-to-match, on the real core, with clip evidence\n" as *u8)
45 let lp: *i64 = sys_mmap(16) as *i64
46 let html: *u8 = sys_read_file("knowledge/status/ocr_bench_page.html\x00" as *u8, lp)
47 if lp[0] <= 0 { fg_puts("find_gate: no bench page\n" as *u8); sys_exit(1); return 1 }
48 let page: *Page = sys_mmap(NX_PAGE_BYTES) as *Page
49 page.raw = html
50 page.raw_len = lp[0]
51 br_layout(page, FG_W)
52 if page.ok != 1 { fg_puts("find_gate: layout failed\n" as *u8); sys_exit(1); return 1 }
53
54 var pass: i64=0
55 var ttl: i64=0
56
57 // T1: find "wizards" (appears once in the pangram paragraph)
58 let yb: *i64 = sys_mmap(16) as *i64
59 let m1: i64 = br_find(page, "wizards\x00" as *u8, 7, yb)
60 ttl=ttl+1; fg_puts(" T1 find 'wizards': matches=" as *u8); fg_num(m1); fg_puts(" (expect 1): " as *u8)
61 if m1==1 { pass=pass+1; fg_puts("PASS\n" as *u8) } else { fg_puts("FAIL\n" as *u8) }
62
63 // T2: first-match y is a real content y (below the h1, above page_h)
64 ttl=ttl+1; fg_puts(" T2 scroll-to target y=" as *u8); fg_num(yb[0]); fg_puts(" (0 < y < page_h " as *u8); fg_num(page.page_h); fg_puts("): " as *u8)
65 if yb[0] > 0 { if yb[0] < page.page_h { pass=pass+1; fg_puts("PASS\n" as *u8) } else { fg_puts("FAIL\n" as *u8) } } else { fg_puts("FAIL\n" as *u8) }
66
67 // T3: highlight pixels present while the find is active
68 let pxa: *u8 = fg_frame(page, 0)
69 let hla: i64 = fg_hl(pxa)
70 ttl=ttl+1; fg_puts(" T3 highlight pixels with find active (got " as *u8); fg_num(hla); fg_puts(" > 100): " as *u8)
71 if hla > 100 { pass=pass+1; fg_puts("PASS\n" as *u8) } else { fg_puts("FAIL\n" as *u8) }
72
73 // T4: clearing the find removes ALL highlight
74 page.find_ptr = 0
75 page.find_len = 0
76 let pxb: *u8 = fg_frame(page, 0)
77 let hlb: i64 = fg_hl(pxb)
78 ttl=ttl+1; fg_puts(" T4 zero highlight pixels with find cleared (got " as *u8); fg_num(hlb); fg_puts("): " as *u8)
79 if hlb == 0 { pass=pass+1; fg_puts("PASS\n" as *u8) } else { fg_puts("FAIL\n" as *u8) }
80
81 // T5 NEG: absent term -> 0 matches, no highlight
82 let m2: i64 = br_find(page, "zzqx\x00" as *u8, 4, yb)
83 let pxn: *u8 = fg_frame(page, 0)
84 let hln: i64 = fg_hl(pxn)
85 ttl=ttl+1; fg_puts(" T5 NEG absent term: matches=" as *u8); fg_num(m2); fg_puts(" highlight=" as *u8); fg_num(hln); fg_puts(": " as *u8)
86 if m2==0 { if hln==0 { pass=pass+1; fg_puts("PASS\n" as *u8) } else { fg_puts("FAIL\n" as *u8) } } else { fg_puts("FAIL\n" as *u8) }
87
88 // T6: case-insensitive
89 let m3: i64 = br_find(page, "WIZARDS\x00" as *u8, 7, yb)
90 ttl=ttl+1; fg_puts(" T6 case-insensitive 'WIZARDS': matches=" as *u8); fg_num(m3); fg_puts(": " as *u8)
91 if m3==1 { pass=pass+1; fg_puts("PASS\n" as *u8) } else { fg_puts("FAIL\n" as *u8) }
92
93 // T7: EVIDENCE CLIP -- plain page, find+highlight, scrolled-to-match
94 let st: *ApngState = sys_mmap(NX_APNG_STATE_BYTES) as *ApngState
95 apng_open(st, "knowledge/status/usersim_find_clip.png\x00" as *u8, FG_W, FG_H, 3, 2, 3)
96 let rgb: *u8 = sys_mmap(FG_W*FG_H*3 + 64)
97 page.find_ptr = 0
98 page.find_len = 0
99 let f1: *u8 = fg_frame(page, 0)
100 fg_rgb(f1, rgb)
101 apng_frame(st, rgb) // frame 1: the page
102 br_find(page, "wizards\x00" as *u8, 7, yb)
103 let f2: *u8 = fg_frame(page, 0)
104 fg_rgb(f2, rgb)
105 apng_frame(st, rgb) // frame 2: highlighted
106 var sy: i64 = yb[0] - 60
107 if sy < 0 { sy = 0 }
108 let f3: *u8 = fg_frame(page, sy)
109 fg_rgb(f3, rgb)
110 apng_frame(st, rgb) // frame 3: scrolled to the match
111 apng_close(st)
112 let cl: *i64 = sys_mmap(16) as *i64
113 cl[0]=0-1
114 let cb: *u8 = sys_read_file("knowledge/status/usersim_find_clip.png\x00" as *u8, cl)
115 ttl=ttl+1; fg_puts(" T7 evidence clip recorded + animated (" as *u8); fg_num(cl[0]); fg_puts("B): " as *u8)
116 var clip_ok: i64 = 0
117 if cl[0] > 50000 { if (cb[37] as i64)==97 { if (cb[38] as i64)==99 { clip_ok=1 } } }
118 if clip_ok==1 { pass=pass+1; fg_puts("PASS\n" as *u8) } else { fg_puts("FAIL\n" as *u8) }
119
120 fg_puts("BROWSER-FIND-GATE passed " as *u8); fg_num(pass); fg_puts("/" as *u8); fg_num(ttl)
121 if pass==ttl { fg_puts(" verdict=GREEN (find-in-page works; watch knowledge/status/usersim_find_clip.png)\n" as *u8); sys_exit(0); return 0 }
122 fg_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1
123}