72 lines
2.8 KiB
Text
72 lines
2.8 KiB
Text
# 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 { return ui_st.ua_sh }
|
|
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)
|
|
return ui_st.ua_sh
|
|
}
|