# cascade.ludic - once the frame's tree is built, every element is styled as a browser would: # the default sheet, then the file's rules from least to most specific, then its style="...", then # its own attributes. Then what is display: none leaves the tree. function cs_tree(ui_st: mut UiState, n: UiNode) -> void { for i in 0 .. len(n.children) { let c = n.children[i] c.parent = n c.index = i } if n.tag != "" { cs_node(ui_st, n) } for i in 0 .. len(n.children) { cs_tree(ui_st, n.children[i]) } var kept = 0 for i in 0 .. len(n.children) { if not n.children[i].hidden { n.children[kept] = n.children[i] kept += 1 } } while len(n.children) > kept { List.pop(n.children) } cs_order(n) } # twice: the font size (and zoom) first, from every rule, so an em anywhere reads the size the # element ends with (again when it zooms, so its own lengths are zoomed) function cs_node(ui_st: mut UiState, n: UiNode) -> void { ui_st.cs_pass = 1 cs_styles(ui_st, n) if zm_own(n) != 1.0 { cs_styles(ui_st, n) } ui_st.cs_pass = 0 cs_styles(ui_st, n) an_apply(ui_st, n) tr_apply(ui_st, n) } function cs_styles(ui_st: mut UiState, n: UiNode) -> void { cs_sheet(ui_st, n, ua_sheet(ui_st)) if n.ups != null { cs_merged(ui_st, n) } else if n.sheet != null { cs_sheet(ui_st, n, n.sheet) } if n.style != null { cs_rule(ui_st, n, n.style) } if n.ups != null { for i in 0 .. len(n.ups) { if n.ups[i].style != null { cs_rule_in(ui_st, n, n.ups[i].style, n.ups[i].env) } } } for i in 0 .. len(n.akeys) { if cs_pass_ok(ui_st, n.akeys[i]) { el_apply(ui_st, n, n.akeys[i], n.vals[i]) } } } function cs_pass_ok(ui_st: UiState, key: string) -> bool { return ui_st.cs_pass == 0 or at_alias(key) == "size" or key == "zoom" } function cs_sheet(ui_st: mut UiState, n: UiNode, sh: UiSheet) -> void { for i in 0 .. len(sh.rules) { let r = sh.rules[i] if md_ok(ui_st, r) and sel_match(ui_st, r.sel, n) { cs_rule(ui_st, n, r) } } } function cs_rule(ui_st: mut UiState, n: UiNode, r: UiRule) -> void { cs_rule_in(ui_st, n, r, n.env) } # a rule's custom properties first, so its other declarations can read them; values read in `e` function cs_rule_in(ui_st: mut UiState, n: UiNode, r: UiRule, e: UiEnv) -> void { for j in 0 .. len(r.keys) { if len(r.keys[j]) > 2 and sat(r.keys[j], 0, "--") { el_attr(ui_st, n, r.keys[j], ui_eval(ui_st, r.vals[j], e)) } } for j in 0 .. len(r.keys) { if not (len(r.keys[j]) > 2 and sat(r.keys[j], 0, "--")) and cs_pass_ok(ui_st, r.keys[j]) { el_attr(ui_st, n, r.keys[j], ui_eval(ui_st, r.vals[j], e)) } } } function ua_sheet(ui_st: mut UiState) -> UiSheet { if ui_st.ua_sh == null { ua_sheet_make(ui_st) } return ui_st.ua_sh } @alloc_ok("once: the default sheet is read the first time a style is asked for") function ua_sheet_make(ui_st: mut UiState) -> void { let f = new UiFile f.path = "the default sheet" f.imp = new []UiFile f.own = new []UiRule lss_text(ui_st, f, UA_LSS) ui_st.ua_sh = sheet_of(f) }