Files
markitect-main/markitect/plugins/testdrive_jsui.py
tegwick 3264517c91 refactor: eliminate duplicate control files and consolidate to capabilities/
- Removed duplicate control files from testdrive-jsui/static/js/controls/
- Removed duplicate control files from markitect/static/js/controls/
- Updated all references to point to capabilities/testdrive-jsui/js/controls/
- Fixed relative paths in test files and templates
- Consolidated to single source of truth in capabilities directory
- Updated plugin configuration and documentation references

This eliminates confusion and ensures all systems use the most recent
control implementations from the capabilities directory.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-14 23:37:17 +01:00

217 lines
7.8 KiB
Python

"""
TestDrive JSUI Rendering Engine Plugin
Independent JavaScript UI rendering engine for Markitect edit mode.
Designed for standalone development and testing of JavaScript components.
"""
from pathlib import Path
from typing import Dict, List, Optional
import json
from .base import PluginMetadata, PluginType
from .rendering import RenderingEnginePlugin, RenderingConfig
class TestDriveJSUIEngine(RenderingEnginePlugin):
"""TestDrive JavaScript UI rendering engine."""
def __init__(self):
super().__init__()
self._metadata = PluginMetadata(
name="testdrive-jsui",
version="1.0.0",
description="Independent JavaScript UI engine for markdown editing",
author="Markitect Team",
plugin_type=PluginType.RENDERING
)
@property
def metadata(self) -> PluginMetadata:
"""Return plugin metadata."""
return self._metadata
def get_supported_modes(self) -> List[str]:
"""Support edit and view modes."""
return ["edit", "view"]
def get_required_assets(self) -> Dict[str, List[str]]:
"""Define required JavaScript, CSS, and other assets."""
return {
"js": [
"static/js/core/debug-system.js",
"static/js/core/section-manager.js",
"static/js/components/debug-panel.js",
"static/js/components/dom-renderer.js",
"../capabilities/testdrive-jsui/js/controls/control-base.js",
"../capabilities/testdrive-jsui/js/controls/contents-control.js",
"../capabilities/testdrive-jsui/js/controls/status-control.js",
"../capabilities/testdrive-jsui/js/controls/debug-control.js",
"../capabilities/testdrive-jsui/js/controls/edit-control.js",
"static/js/config-loader.js",
"static/js/main-updated.js"
],
"css": [
"static/css/editor.css",
"static/css/controls.css",
"static/css/themes/github.css"
],
"images": [
"images/icons/edit.png",
"images/icons/save.png",
"images/icons/reset.png"
],
"external": [
"https://cdn.jsdelivr.net/npm/marked/marked.min.js"
]
}
def get_template_path(self) -> Optional[Path]:
"""Return path to the HTML template."""
# Look for template in plugin directory structure
plugin_dir = Path(__file__).parent.parent.parent / "testdrive-jsui"
template_path = plugin_dir / "templates" / "index.html"
if template_path.exists():
return template_path
# Fallback to current template location
return Path(__file__).parent.parent / "templates" / "edit-mode-fixed.html"
def render_document(self,
content: str,
mode: str,
config: RenderingConfig) -> str:
"""
Render markdown content using TestDrive JSUI.
Args:
content: Markdown content to render
mode: Rendering mode ('edit' or 'view')
config: Rendering configuration
Returns:
Complete HTML document
"""
if not self.validate_mode(mode):
raise ValueError(f"Mode '{mode}' not supported by TestDrive JSUI engine")
# Get template
template_path = self.get_template_path()
if not template_path or not template_path.exists():
raise FileNotFoundError(f"Template not found: {template_path}")
# Load template content
with open(template_path, 'r', encoding='utf-8') as f:
template_content = f.read()
# Generate asset URLs
assets = self.get_required_assets()
js_scripts = []
css_links = []
# External dependencies
for external_url in assets.get("external", []):
js_scripts.append(f'<script src="{external_url}"></script>')
# Plugin assets
for js_file in assets.get("js", []):
url = config.get_asset_url(self.metadata.name, js_file)
js_scripts.append(f'<script src="{url}"></script>')
for css_file in assets.get("css", []):
url = config.get_asset_url(self.metadata.name, css_file)
css_links.append(f'<link rel="stylesheet" href="{url}">')
# Generate configuration JSON for JavaScript
js_config = {
"markdownContent": content,
"markdownContentWithDogtag": content, # Could add dogtag here
"dogtagContent": "",
"mode": mode,
"theme": "github",
"keyboardShortcuts": True,
"autosave": False,
"sections": True,
"originalFilename": "document",
"base64References": {},
"version": f"Markitect {self.metadata.version}",
"repoName": "Markitect"
}
# Basic fallback content rendering (simple markdown to HTML)
fallback_html = self._render_markdown_fallback(content)
# Replace template placeholders using safe substitution
html_content = template_content
html_content = html_content.replace("{title}", "TestDrive JSUI Document")
html_content = html_content.replace("{version}", f"Markitect {self.metadata.version}")
html_content = html_content.replace("{mode_class}", f"markitect-{mode}-mode")
html_content = html_content.replace("{css_content}", "\n".join(css_links))
html_content = html_content.replace("{js_scripts}", "\n".join(js_scripts))
html_content = html_content.replace("{config_json}", json.dumps(js_config, indent=2))
html_content = html_content.replace("{fallback_content}", fallback_html)
return html_content
def _render_markdown_fallback(self, content: str) -> str:
"""
Render basic markdown to HTML for fallback content.
Args:
content: Markdown content
Returns:
Basic HTML rendering
"""
import re
# Very basic markdown to HTML conversion for fallback
html = content
# Headers
html = re.sub(r'^# (.+)$', r'<h1>\1</h1>', html, flags=re.MULTILINE)
html = re.sub(r'^## (.+)$', r'<h2>\1</h2>', html, flags=re.MULTILINE)
html = re.sub(r'^### (.+)$', r'<h3>\1</h3>', html, flags=re.MULTILINE)
# Paragraphs
html = re.sub(r'\n\n', '</p><p>', html)
html = re.sub(r'\n', '<br>', html)
# Wrap in paragraph tags
if html.strip() and not html.startswith('<'):
html = f'<p>{html}</p>'
return html
def get_development_config(self, source_dir: Path) -> RenderingConfig:
"""
Get development configuration for standalone testing.
Args:
source_dir: Path to testdrive-jsui source directory
Returns:
Development rendering configuration
"""
return RenderingConfig(
asset_base_url=".", # Serve from current directory in dev
development_mode=True,
plugin_source_dirs={self.metadata.name: source_dir}
)
def create_standalone_test_document(self,
test_content: str,
output_path: Path) -> None:
"""
Create a standalone HTML document for testing.
Args:
test_content: Markdown content to test with
output_path: Where to write the test HTML file
"""
config = self.get_development_config(output_path.parent)
html_content = self.render_document(test_content, "edit", config)
output_path.write_text(html_content, encoding='utf-8')
print(f"✅ Created standalone test document: {output_path}")