| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- 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<DemoHostComponent>();
- * 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 """
- <div class="demo-host" sid="host">
- <div class="demo-header">
- <span class="demo-title" sid="title">Demo</span>
- <div class="demo-toggle-group">
- <button class="demo-toggle-btn" spry-action=":ShowDemo" spry-target="host"
- class-active-expr="!this.showing_source">Demo</button>
- <button class="demo-toggle-btn" spry-action=":ShowSource" spry-target="host"
- class-active-expr="this.showing_source">Source</button>
- </div>
- </div>
- <div class="demo-content" sid="content">
- <div spry-if="!this.showing_source">
- <spry-outlet sid="demo-outlet"/>
- </div>
- <div spry-if="this.showing_source">
- <pre class="demo-source"><code sid="source-code"></code></pre>
- </div>
- </div>
- </div>
- """;
- }}
-
- 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 <pre><code> blocks
- */
- private string escape_html(string input) {
- var result = input
- .replace("&", "&")
- .replace("<", "<")
- .replace(">", ">")
- .replace("\"", """)
- .replace("'", "'");
- return result;
- }
- }
|