运行时与更新
MountAsync
MountAsync 会遍历元素树、分配 NodeHandle、写入 CreateElement、属性、样式、
文本、监听器以及最终的 SetRoot opcode,并把 frame 发送到 WebKitGTK renderer。
await using var host = RenderHostFactory.CreateWebKitGtk();
var app = App.Create(host);
var root = new Div();
root.Children.Add(new Button("Save"));
await app.MountAsync(root, cancellationToken);
await host.RunAsync(cancellationToken);
Update
Update 和 UpdateAsync 提交 imperative DOM update transaction。事务会复用
已挂载元素的 handle,并在一个 frame 中写入文本、属性、样式、子节点或监听器变更。
await app.UpdateAsync(tx => tx
.SetText(button, "Saved")
.SetAttr(button, "class", "primary")
.SetStyle(button, StylePropId.FontSize, 16), cancellationToken);
HTML / CSS Load
WebKitGTK host 可以直接加载 HTML 和 CSS:
await using var host = RenderHostFactory.CreateWebKitGtk();
await host.LoadHtmlAsync("<main><h1>Hello</h1></main>");
await host.LoadCssAsync("h1 { color: rgb(1, 2, 3); }");
LoadHtmlAsync 默认不允许 HTML 自带 JavaScript。加载前会通过浏览器 DOM parser
解析并清理 <script>、iframe、object、embed、meta[http-equiv]、
inline event handler、srcdoc 和 javascript: URL,然后再替换当前 document
的 head/body。框架内部的 shim 仍然可以继续工作。
LoadCssAsync(css) 会写入默认 stylesheet。LoadCssAsync(css, styleId) 会写入
或替换同名 stylesheet,适合主题或热更新样式。
子节点 transaction 支持创建新子树、插入、移动、分离和销毁:
var item = new Li("New");
app.Update(tx => tx
.InsertBefore(list, item, before)
.MoveBefore(list, item, null)
.RemoveChild(list, oldItem)
.RemoveNode(item));
RemoveChild 只把子树从父节点分离,节点 handle 仍可再次插入。RemoveNode 会
销毁 renderer 侧节点、释放 arena row,并清理该子树的 listener binding。
事件监听器
监听器通过 ListenerRegistry 映射到 wire token。renderer 只回传 token 和事件
payload,C# 侧再按 token、event id 和 node id 确认 binding 后解析并调用对应
delegate。
Action handler = () => Console.WriteLine("clicked");
app.Update(tx => tx.AddListener(button, eventId: 1, handler));
app.Update(tx => tx.RemoveListener(button, eventId: 1, handler));
RemoveListener 要求传入之前注册过的同一个 delegate identity;未注册的移除会
抛出异常,避免向 renderer 发送无意义 token。
同一个 delegate 可以绑定到多个节点;移除其中一个节点的监听器不会影响其他节点。
销毁节点或 dispose app 时,C# registry 会清理对应 binding,renderer shim 也会在
RemoveNode 时清理 listener 表。
Dispose
UltimateUiApp 实现 IAsyncDisposable。Dispose 会取消 inbound 事件订阅、清空
listener registry,并释放绑定的 IRenderHost 或 IDomBackend。