webui_handler/plugin.rs
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT license.
3
4//! Handler plugin trait and built-in plugin implementations.
5//!
6//! The plugin system is framework-agnostic — WebUI provides lifecycle hooks
7//! and plugins decide what (if anything) to write. Different frameworks
8//! (FAST, LIT, etc.) implement `HandlerPlugin` with their own marker formats.
9
10mod fast;
11
12pub use fast::FastHydrationPlugin;
13
14use crate::{ResponseWriter, Result};
15
16/// A handler plugin that can inject additional content during rendering.
17///
18/// Plugins receive callbacks at key points in the rendering lifecycle:
19/// - **Scope management**: `push_scope` / `pop_scope` for component and loop boundaries
20/// - **Binding lifecycle**: `on_binding_start` / `on_binding_end` around signals, for-loops, if-conditions
21/// - **Repeat items**: `on_repeat_item_start` / `on_repeat_item_end` per for-loop item
22/// - **Plugin data**: `on_plugin_data` for opaque data from parser plugins
23///
24/// WebUI does not interpret what plugins write — it just calls the hooks.
25/// Each framework defines its own marker format.
26pub trait HandlerPlugin {
27 /// Enter a new scope (component or for-loop item boundary).
28 /// Typically resets per-scope counters.
29 fn push_scope(&mut self);
30
31 /// Exit the current scope, restoring the parent scope state.
32 fn pop_scope(&mut self);
33
34 /// Called before rendering a binding (signal, for-loop, or if-condition).
35 fn on_binding_start(&mut self, name: &str, writer: &mut dyn ResponseWriter) -> Result<()>;
36
37 /// Called after rendering a binding.
38 fn on_binding_end(&mut self, name: &str, writer: &mut dyn ResponseWriter) -> Result<()>;
39
40 /// Called before rendering a repeat item in a for loop.
41 fn on_repeat_item_start(&mut self, index: usize, writer: &mut dyn ResponseWriter)
42 -> Result<()>;
43
44 /// Called after rendering a repeat item.
45 fn on_repeat_item_end(&mut self, index: usize, writer: &mut dyn ResponseWriter) -> Result<()>;
46
47 /// Called when a plugin-specific protocol fragment is encountered.
48 /// The data is opaque bytes from the parser plugin — interpretation is plugin-defined.
49 fn on_plugin_data(&mut self, data: &[u8], writer: &mut dyn ResponseWriter) -> Result<()>;
50
51 /// Called after all fragments have been rendered.
52 fn on_render_complete(
53 &mut self,
54 _protocol: &webui_protocol::WebUIProtocol,
55 _rendered_components: &std::collections::HashSet<String>,
56 _writer: &mut dyn ResponseWriter,
57 ) -> Result<()> {
58 Ok(())
59 }
60}