name: CodeEditor
purpose: Edit source text with syntax highlighting, diagnostics, reindentation, and optional Markdown or sandboxed HTML preview.

attributes:
  lang: "javascript|js|json|yaml|yml|python|py|html|css|markdown|md; overrides path extension detection."
  path: File path used for language detection and optional Editor document transport.
  api: Optional Editor document endpoint; requires path for automatic loading and saving.
  version: Optional document history version passed to Editor transport.
  value: Initial source string.
  theme: "auto|light|dark; defaults to auto and follows the page data-bs-theme."
  wrap: boolean; wrap long source lines inside this editor instance.
  readonly: boolean
  mode: "source|split|preview; Markdown and HTML only, otherwise source."
  previewscripts: boolean; allow scripts in HTML preview inside a sandbox without same-origin permission.
  previewauto: boolean; rerun script-enabled HTML after each edit; otherwise explicit refresh is required.
  allowhtml: boolean; parse raw HTML inside Markdown preview before sanitizing it.
  breaks: boolean; convert Markdown paragraph line breaks to br elements.
  toolbar: boolean; opt in to the component's built-in toolbar. By default tools are exposed only through the Editor toolbar API.
  notoolbar: boolean; compatibility override that hides the built-in toolbar even when toolbar is present.

properties:
  value: Current source string; compatible with $bind and AutoForm type code.
  language: Normalized active language name.
  mode: Current source, split, or preview mode; assigning it also updates the mode attribute.
  view: CodeMirror EditorView after ready resolves.
  ready: Promise resolving to the component after its on-demand language bundle loads.
  diagnostics: Current syntax diagnostics.
  documentMode: True when path, api, or version enables Editor document behavior.
  editorTools: Source toolbar command descriptors supplied through Editor.setTools.

methods:
  reindent: Reindent the complete document using the active language indentation rules and return value.
  setWrap: "setWrap(boolean) — enable or disable line wrapping for this editor instance."
  validate: Return current parser syntax diagnostics and update diagnostics.
  focus: Focus the CodeMirror editing surface.
  setMode: "setMode(source|split|preview) — switch panes and return the effective mode."
  refreshPreview: Render the current Markdown or HTML source and return a Promise<boolean>.
  load: Added by Editor in document mode; load source text from api and path.
  save: Added by Editor in document mode; save a code document envelope.
  getTools: Return resolved source, preview, split, validate, and reindent tool descriptors.
  runTool: Execute a published editor tool by id.

events:
  ready: "detail=CodeEditor after the language bundle and view are ready."
  input: Bubbles after an interactive document change for $bind compatibility.
  change: "detail=source string after an interactive document change or reindent."
  diagnostics: "detail=array of parser syntax diagnostics whenever the result changes."
  modechange: "detail=effective source|split|preview mode."
  preview: "detail={ language, source } after Markdown or HTML preview refreshes."
  loaded: In document mode, detail is the loaded Editor document envelope.
  save: In document mode, cancelable with detail equal to the outgoing document envelope.
  saved: In document mode, detail is the save response.
  error: "detail=Error from language, preview, or Editor transport loading."
  toolschange: "detail=resolved toolbar descriptors after capabilities, preview availability, or active state change."

languages:
  javascript: ".js|.mjs|.cjs; aliases js and javascript."
  json: .json
  yaml: ".yaml|.yml; aliases yaml and yml."
  python: ".py; aliases py and python."
  html: ".html|.htm; aliases html and htm."
  css: .css
  markdown: ".md|.markdown; aliases md and markdown."

preview:
  markdown: Sanitized Markdown rendered in the preview pane; its parser library loads only when first needed.
  html: Source assigned to iframe srcdoc. Scripts are disabled by default.
  html_scripts: previewscripts uses sandbox="allow-scripts" without allow-same-origin, top navigation, forms, popups, or downloads.
  refresh_policy: Markdown and script-free HTML update after edits. Script-enabled HTML becomes stale and waits for Refresh unless previewauto is present.
  responsive: Split mode uses equal columns and changes to stacked equal regions below the Bootstrap md breakpoint.

validation:
  scope: Parser-level syntax errors only; no code execution, semantic lint, or type checking.
  timing: Diagnostics refresh after editing becomes idle; validate performs an immediate read of the current syntax tree.

reindent:
  scope: Leading indentation is recalculated from the active language syntax tree; source tokens are not rewritten.

rules:
  - Explicit lang takes precedence over path extension; JavaScript is the fallback.
  - The shared CodeMirror core loads once and each language bundle loads only when first requested.
  - Preview modes are available only for Markdown and HTML; other languages remain in source mode.
  - HTML preview isolation reduces page privileges but is not a substitute for a separate origin when running untrusted hostile code.
  - AutoForm mode is a plain string control and does not enable Editor transport.
  - Line wrapping is an instance display preference; it does not change document data or other editor instances.
  - The optional compact toolbar presents source, vertical split, horizontal split, and preview as an icon-only exclusive view group.
  - Editor document mode is enabled only by path, api, state.path, or version and stores source text in state.data.

examples:
  direct: |
    <CodeEditor path="scripts/app.js" value="function run(){\nconsole.log('ok')\n}"></CodeEditor>
    <button $onclick="document.querySelector('CodeEditor').reindent()">Reindent</button>
  markdown_split: |
    <CodeEditor path="README.md" mode="split" wrap style="height:480px" value="# Hello"></CodeEditor>
  html_script_preview: |
    <CodeEditor path="page.html" mode="split" previewscripts style="height:480px"></CodeEditor>
  autoform: |
    <script>
      const formData = { config: '{"enabled":true}' }
      const formSchema = [{ name: 'config', label: 'Configuration', type: 'code', setting: { lang: 'json', style: 'height:220px' } }]
    </script>
    <AutoForm $.state.data="formData" $.state.schema="formSchema"></AutoForm>
  editor_document: |
    <CodeEditor api="/documents" path="scripts/task.py"></CodeEditor>

related:
  - MarkdownViewer.yaml
  - ../../utilities/Editor.yaml
  - ../base/AutoForm.yaml

tests:
  - CodeEditor.test.html
