Skip to main content

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}