Project: Markdown editor with WebView
This project upgrades the Module 4 markdown editor from Wx::HTML::HtmlWindow to Wx::WEB::WebView. The model and editor panel are completely unchanged. Only PreviewPanel is different — and the improvement is immediately visible.
|
|
Requires internet access for highlight.js CDN.
Download markdown_editor_v2.zip
What changed — and what didn’t
The key architectural point of this project is what stayed the same. Open editor_frame.rb and compare it to the Module 4 version. They are identical except for the require_relative paths.
The frame calls:
|
|
It does not know or care whether PreviewPanel uses HtmlWindow or WebView. The public interface is the same. Swapping the implementation required touching exactly one file.
The new PreviewPanel
lib/panels/preview_panel.rb is the only file that changed. It now uses JsBridge to call a JS method on the page:
|
|
The JS side receives the rendered HTML and applies syntax highlighting:
|
|
The ready pattern from lesson 5.2 is applied — Ruby triggers ready after registering the handler:
|
|
The preview page
lib/html/preview_page.rb contains the complete WebView page as a Ruby module. It loads two external resources from CDN:
|
|
And uses full CSS for typography, code blocks, tables, and blockquotes — none of which was possible with HtmlWindow.
What improved over HtmlWindow
| Feature | HtmlWindow | WebView |
|---|---|---|
| CSS stylesheets | Limited | ✓ Full |
| Syntax highlighting | ✗ | ✓ via highlight.js |
| Table styling | Basic | ✓ Custom |
| Blockquote styling | Basic | ✓ Custom |
| Typography control | Limited | ✓ Full |
| Code font and colours | System default | ✓ Controlled |
| JavaScript | ✗ | ✓ |
The visual difference is striking. Open both editors side by side — the same markdown source renders very differently. The WebView version looks like a real documentation tool.
The debounce timer and ready
One subtlety worth noting: load_sample_content sets up the initial content and starts the debounce timer. But when the timer fires, the WebView may not be ready yet — the page is still loading. The return unless @ready guard in PreviewPanel#update handles this correctly — the first update is silently dropped, and the user can trigger another by typing.
For a production app you might store the pending HTML and send it immediately when ready fires. For this tutorial app the behaviour is acceptable.
What this project demonstrates
- The value of interface-based panel design — swap
PreviewPanel, touch nothing else - Full
JsBridgepattern in a real editing workflow - CDN resources in WebView pages
- Syntax highlighting with highlight.js — two lines of JS, zero Ruby changes
- The ready pattern correctly applied
Previous: Leaflet maps | Next: Module 6 — Real-world applications