code wiki / _hdl_build / nx_css_boxmap_test.nx

nx_css_boxmap_test.nx source

↩ module page · 154 lines · 7972 B

1// nx_css_boxmap_test.nx -- styling rung 3: map the cascade onto LAYOUT BOXES. nx_layout_block looks up 2// computed style by box-index (cd.element_idx == box_idx), and the tree has a synthetic root + text + 3// anonymous boxes, so we build a CssElement[] indexed BY BOX: each element box (BLOCK/INLINE, not the 4// root, not text/anon) gets the next document-order extracted element's tag/id/class; text/anon blank. 5// Then nx_css_apply -> computed decls keyed by box_idx -> layout/paint lookups hit. Gate proves the h1 6// BOX receives font-size:32px (alignment correct). expect_exit: 0. 7import "nx_syscalls.nx" 8import "nx_html_tokenizer.nx" 9import "nx_dom_query.nx" 10import "nx_css_selector_match.nx" 11import "nx_css_tokenize.nx" 12import "nx_css_parse.nx" 13import "nx_css_apply.nx" 14import "nx_layout_box.nx" 15import "nx_layout_default_display.nx" 16import "nx_layout_from_dom.nx" 17 18func bm_slen(s: *u8) -> i64 { var k: i64=0; while s[k]!=(0 as u8){k=k+1} return k } 19func bm_puts(s: *u8) -> i64 { sys_write(1, s, bm_slen(s)); return 0 } 20func bm_pn(v: i64) -> i64 { let b: *u8=sys_mmap(20); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m}; let t: *u8=sys_mmap(20); var k: i64=0; if m==0{t[0]=48;k=1}; while m>0{t[k]=48+(m%10);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 } 21func bm_region_is(src: *u8, off: i64, len: i64, lit: *u8) -> i64 { 22 let ll: i64 = bm_slen(lit) 23 if len != ll { return 0 } 24 var i: i64 = 0 25 while i < ll { if (src[off+i] & 0xff) != (lit[i] & 0xff) { return 0 } i = i + 1 } 26 return 1 27} 28// extract elements from HTML (doc order, tags + id/class), like rung 1. 29func bm_extract(html: *u8, hlen: i64, elements: *CssElement, maxn: i64) -> i64 { 30 let c: *HtmlCursor = sys_mmap(24) as *HtmlCursor 31 nx_html_cursor_init(c, html, hlen) 32 let tok: *HtmlToken = sys_mmap(56) as *HtmlToken 33 let ao: *i64=sys_mmap(8) as *i64; let al: *i64=sys_mmap(8) as *i64; let bo: *i64=sys_mmap(8) as *i64; let bl: *i64=sys_mmap(8) as *i64 34 var n: i64 = 0 35 while 1 == 1 { 36 nx_html_next_token(c, tok) 37 if tok.kind == NX_HTML_TOK_EOF { return n } 38 if n >= maxn { return n } 39 var ie: i64 = 0 40 if tok.kind == NX_HTML_TOK_START_TAG { ie = 1 } 41 if tok.kind == NX_HTML_TOK_SELF_CLOSING { ie = 1 } 42 if ie == 1 { 43 let e: *CssElement = ((elements as i64) + n * NX_CSS_ELEMENT_BYTES) as *CssElement 44 e.src = html 45 e.tag_off = tok.name_off; e.tag_len = tok.name_len 46 if nx_dom_find_attr(html, tok.src_off, tok.src_len, "id\x00" as *u8, ao, al) == 1 { e.id_off=ao[0]; e.id_len=al[0] } else { e.id_off=0; e.id_len=0 } 47 if nx_dom_find_attr(html, tok.src_off, tok.src_len, "class\x00" as *u8, bo, bl) == 1 { e.class_off=bo[0]; e.class_len=bl[0] } else { e.class_off=0; e.class_len=0 } 48 n = n + 1 49 } 50 } 51 return n 52} 53func bm_is_elem_kind(k: i64) -> i64 { 54 if k == NX_LAYOUT_BOX_BLOCK { return 1 } 55 if k == NX_LAYOUT_BOX_INLINE { return 1 } 56 if k == NX_LAYOUT_BOX_INLINE_BLOCK { return 1 } 57 return 0 58} 59 60func main() -> i64 { 61 let htmls: *u8 = "<html><body><h1 id='t'>Hi</h1><a href='/y'>L</a><p>x</p></body></html>\x00" 62 let csss: *u8 = "h1{font-size:32px}a{color:#0000ff}\x00" 63 let hlen: i64 = bm_slen(htmls) 64 let clen: i64 = bm_slen(csss) 65 let total: i64 = hlen + clen 66 let buf: *u8 = sys_mmap(total + 16) 67 var i: i64 = 0 68 while i < hlen { buf[i] = htmls[i]; i = i + 1 } 69 i = 0 70 while i < clen { buf[hlen + i] = csss[i]; i = i + 1 } 71 72 // extracted elements (doc order, tags), src = combined buffer 73 let ext: *CssElement = (sys_mmap(NX_CSS_ELEMENT_BYTES * 64) as nx_size) as *CssElement 74 let n_ext: i64 = bm_extract(buf, hlen, ext, 64) 75 76 // layout the HTML part -> box tree 77 let boxes: *LayoutBox = (sys_mmap(NX_LAYOUT_BOX_BYTES * 512 + 16)) as *LayoutBox 78 let tree: *LayoutTree = (sys_mmap(64)) as *LayoutTree 79 nx_layout_tree_init(tree, boxes, 512) 80 let stk: *LayoutFromDomStack = (sys_mmap(NX_LAYOUT_FROM_DOM_STACK_BYTES + 8)) as *LayoutFromDomStack 81 let stk_idx: *i64 = (sys_mmap(8 * 128)) as *i64 82 nx_layout_from_dom_stack_init(stk, stk_idx, 128) 83 nx_layout_from_dom(buf, hlen, tree, stk) 84 85 // build CssElement[] indexed BY BOX INDEX 86 let boxel: *CssElement = (sys_mmap((NX_CSS_ELEMENT_BYTES * (tree.count + 1)) as nx_size)) as *CssElement 87 var k: i64 = 0 88 var h1_box: i64 = 0 - 1 89 i = 0 90 while i < tree.count { 91 let b: *LayoutBox = ((tree.boxes as i64) + i * NX_LAYOUT_BOX_BYTES) as *LayoutBox 92 let e: *CssElement = ((boxel as i64) + i * NX_CSS_ELEMENT_BYTES) as *CssElement 93 e.src = buf 94 var mapped: i64 = 0 95 if bm_is_elem_kind(b.kind) == 1 { if b.parent_idx != (0 - 1) { if k < n_ext { 96 let s: *CssElement = ((ext as i64) + k * NX_CSS_ELEMENT_BYTES) as *CssElement 97 e.tag_off = s.tag_off; e.tag_len = s.tag_len 98 e.id_off = s.id_off; e.id_len = s.id_len 99 e.class_off = s.class_off; e.class_len = s.class_len 100 if bm_region_is(buf, s.tag_off, s.tag_len, "h1\x00" as *u8) == 1 { h1_box = i } 101 k = k + 1 102 mapped = 1 103 } } } 104 if mapped == 0 { e.tag_off=0; e.tag_len=0; e.id_off=0; e.id_len=0; e.class_off=0; e.class_len=0 } 105 i = i + 1 106 } 107 108 // parse the UA CSS region + cascade over boxel (tree.count entries) 109 let cur: *CssCursor = (sys_mmap(NX_CSS_CURSOR_BYTES) as nx_size) as *CssCursor 110 nx_css_cursor_init(cur, buf, total) 111 cur.pos = hlen 112 let tok: *CssToken = (sys_mmap(NX_CSS_TOKEN_BYTES) as nx_size) as *CssToken 113 let rules: *CssRule = (sys_mmap(NX_CSS_RULE_BYTES * 32) as nx_size) as *CssRule 114 let decls: *CssDeclaration = (sys_mmap(NX_CSS_DECLARATION_BYTES * 64) as nx_size) as *CssDeclaration 115 let st: *CssParseState = (sys_mmap(128) as nx_size) as *CssParseState 116 nx_css_parse_state_init(st, cur, tok, rules, 32, decls, 64) 117 nx_css_parse(st) 118 let computed: *CssComputedDecl = (sys_mmap(NX_CSS_COMPUTED_DECL_BYTES * 256) as nx_size) as *CssComputedDecl 119 let cb: *i64 = (sys_mmap(8)) as *i64 120 nx_css_apply(buf, rules, st.rule_count, decls, st.decl_count, boxel, tree.count, computed, 256, cb) 121 let ncomp: i64 = cb[0] 122 123 var pass: i64 = 0 124 var tot: i64 = 0 125 bm_puts("nx_css_boxmap gate (styling rung 3: cascade keyed by BOX index)\n" as *u8) 126 127 // ---- KAT1: every extracted element got mapped to an element box (k == n_ext) ---- 128 var r1: i64 = 0 129 if k == n_ext { if n_ext == 5 { r1 = 1 } } 130 if r1 == 1 { bm_puts(" PASS KAT1 element-boxes mapped = extracted elements = 5 (html/body/h1/a/p)\n" as *u8); pass=pass+1 } else { bm_puts(" FAIL KAT1 k=" as *u8); bm_pn(k); bm_puts(" n_ext=" as *u8); bm_pn(n_ext); bm_puts(" boxes=" as *u8); bm_pn(tree.count); bm_puts("\n" as *u8) } 131 tot = tot + 1 132 133 // ---- KAT2: the h1 BOX received computed font-size 32 (alignment correct) ---- 134 var r2: i64 = 0 135 if h1_box >= 0 { 136 var j: i64 = 0 137 while j < ncomp { 138 let cd: *CssComputedDecl = ((computed as i64) + j * NX_CSS_COMPUTED_DECL_BYTES) as *CssComputedDecl 139 if cd.element_idx == h1_box { 140 if bm_region_is(buf, cd.prop_off, cd.prop_len, "font-size\x00" as *u8) == 1 { 141 if bm_region_is(buf, cd.val_off, cd.val_len, "32\x00" as *u8) == 1 { r2 = 1 } 142 } 143 } 144 j = j + 1 145 } 146 } 147 if r2 == 1 { bm_puts(" PASS KAT2 the h1 BOX (idx " as *u8); bm_pn(h1_box); bm_puts(") got computed font-size 32 -> cascade aligns to boxes\n" as *u8); pass=pass+1 } else { bm_puts(" FAIL KAT2 h1_box=" as *u8); bm_pn(h1_box); bm_puts(" ncomp=" as *u8); bm_pn(ncomp); bm_puts("\n" as *u8) } 148 tot = tot + 1 149 150 bm_puts("---- nx_css_boxmap gate: passed " as *u8); bm_pn(pass); bm_puts(" / " as *u8); bm_pn(tot); bm_puts("\n" as *u8) 151 if pass == tot { sys_exit(0); return 0 } 152 sys_exit(1) 153 return 1 154}