using Spry; /** * DemoHostComponent - A component that hosts demo implementations with source/demo toggle * * This component provides a frame for demo content with the ability to toggle * between viewing the demo and viewing the source code. * * Usage: * var host = factory.create(); * host.source_file = "examples/CounterComponent.vala"; * host.set_outlet_child("demo-outlet", demo_component); */ public class DemoHostComponent : Component { /// Path to the source file to display (relative to project root) public string source_file { get; set; default = ""; } /// Toggle state - true when showing source code public bool showing_source { get; set; default = false; } /// The loaded source code content (cached after first load) private string? _source_content = null; public override string markup { get { return """
Demo
"""; }} public override async void prepare() throws Error { // Update the source code display if we're showing source if (showing_source && _source_content != null) { this["source-code"].text_content = _source_content; } } public async override void handle_action(string action) throws Error { switch (action) { case "ShowDemo": showing_source = false; break; case "ShowSource": if (_source_content == null) { _source_content = yield load_source_file(); } showing_source = true; break; } } /** * Load the source file from disk and escape HTML entities */ private async string load_source_file() { try { // Try to read from the project root (relative path) var file = File.new_for_path(source_file); if (!file.query_exists()) { return @"Error: Source file not found: $source_file"; } uint8[] contents; string etag_out; yield file.load_contents_async(null, out contents, out etag_out); var source = (string)contents; return escape_html(source); } catch (Error e) { return @"Error loading source file: $(e.message)"; } } /** * Escape HTML entities for safe display in
 blocks
     */
    private string escape_html(string input) {
        var result = input
            .replace("&", "&")
            .replace("<", "<")
            .replace(">", ">")
            .replace("\"", """)
            .replace("'", "'");
        return result;
    }
}