Donner 0.8.0-pre
Embeddable browser-grade SVG2 engine
Loading...
Searching...
No Matches
Editor Source Focus

Overview

The editor source pane is a view over XMLDocument::source(). Source focus mode, CSS provenance, hover preview, soft wrap, and source flashes are view-layer features on top of that source buffer. They do not create a second source store, rewrite XML, or change save output.

Source focus mode is enabled by default. Users can toggle it from the View menu, the source editor context menu, or Cmd+Enter on macOS and Ctrl+Enter on other platforms. When enabled, the source pane folds unrelated lines, keeps selected elements and their referenced resources visible, dims structural ancestor context, and draws reference arrows between source refs and target elements.

Moving the source cursor updates the canvas/tree selection when the cursor lands inside an SVG element. Hovering source text is non-mutating: it highlights the corresponding shape in the render pane and adds a subtle source highlight without changing selection. Elements already in the active selection do not get duplicate source-hover highlights.

Architecture Snapshot

FocusView computes the source partition. Its public entry points live in donner/editor/FocusView.h:

  • ComputeFocusPartition(document, selected) computes focus for one selected element.
  • ComputeFocusPartition(document, selectedElements) computes the union for multi-selection.
  • ComputeStyleFocusAtSourceOffset(document, sourceOffset) handles reverse CSS focus when the cursor is inside a source-backed stylesheet rule.

FocusPartition contains:

  • fullColor: selected elements, referenced resources, matched CSS rules, and reverse CSS impacted elements.
  • dimmed: ancestor opening and closing tag context, including the surrounding <style> element when a visible rule is inside a style block.
  • hidden: folded line ranges outside the focus set.
  • referenceLinks: source-point pairs for reference arrows.

Reference traversal follows same-document resource refs from selected rendered content, including paint refs, filter/mask/clip refs, href chains, inline style refs, and CSS declaration refs. When a selected group contains children, child refs contribute arrows and resource visibility too.

CSS provenance stays in Donner's CSS and style layers:

TextEditor renders the partition. It owns soft-wrap visual rows, hidden-range placeholders, hover source ranges, source flashes, and reference connector layout. Soft wrap maps logical source lines to visual rows without changing logical line/column or byte offsets.

EditorShell bridges text interactions to app selection:

  • cursor movement resolves a source offset to the nearest/deepest SVG element;
  • cursor movement inside a style rule applies reverse CSS focus and selects the impacted elements;
  • hover resolves source text to transient render-pane hover chrome;
  • menu and keyboard actions toggle focus mode.

RenderCoordinator owns transient source-hover elements separately from real selection. OverlayRenderer draws hover chrome without resize handles and without mutating editor selection.

Source Pane Behavior

Focus-hidden ranges render as compact ... rows. Clicking a placeholder expands that hidden range in place without changing focus mode or selection.

Reference arrows are pastel, baseline-aligned connectors. They start at the reference token, travel right, use staggered vertical lanes between the rightmost text and scrollbar, return left to the target opening <, and end with an arrowhead at the target baseline.

Text selection suppresses source-selection sync and does not scroll the source pane. UI-driven selection still scrolls the source pane to the selected element. Wrap-aware scrolling uses visual rows, so selecting an element on a wrapped line scrolls to the visible row containing the selected source.

Typing inside the current source-focus range preserves the existing editor selection and source caret while the structured edit is applied. Cursor navigation outside that focus range can still select the element at the source cursor.

When focus originated from a CSS rule, moving the caret from the rule to one of the visible impacted elements does not immediately recompute focus from the element's current attributes. This keeps the active CSS rule visible while the user edits a matching class attribute through temporarily mismatched or unparseable intermediate text.

Changed-source flashes are byte-range decorations managed by FlashDecorations. Flashes are used for editor-driven source updates such as canvas/DOM writebacks, not for bytes the user just typed in the source pane. Flashes are capped, clamped to the current buffer, shifted or dropped across later edits, and rendered through the same visual-row path as hover highlights.

Implementation Locators

Security and Safety

Source text and source offsets are treated as untrusted. Decorations clamp byte ranges to the current buffer before indexing. Stale or unmappable CSS source ranges produce no decoration instead of falling back to text search.

Focus mode stores line ranges and source-point links, not a copied text buffer. Soft wrap and folding are render filters over the same logical source. Undo, redo, parsing, save, and source-offset mapping continue to operate in the original source coordinate space.

Non-rendered resource elements, such as gradient <stop> nodes, do not show wildcard selector provenance as though they were directly styled renderable shapes.

Testing

Primary test locators:

  • donner/editor/tests/FocusView_tests.cc: focus partitions, resource traversal, CSS rule visibility, reverse CSS focus, hidden placeholders, and focus-set cleanup.
  • donner/editor/tests/TextEditor_tests.cc: wrap-aware hit testing, selection scrolling, reference arrow layout, hover tracking, source hover ranges, and context-menu focus toggles.
  • donner/editor/tests/SourceSelection_tests.cc: source-offset, caret-near-tag, and element source-range lookup.
  • donner/editor/tests/OverlayRenderer_tests.cc: transient source-hover chrome.
  • donner/editor/tests/KeyboardShortcutPolicy_tests.cc: Cmd+Enter / Ctrl+Enter focus-mode shortcut eligibility.
  • donner/editor/tests/SoftWrap_tests.cc: XML-aware wrapping and indentation.
  • donner/editor/tests/FlashDecorations_tests.cc: flash lifetime, clamping, adjustment across edits, and cap behavior.
  • donner/css/parser/tests/StylesheetParser_tests.cc: CSS rule and selector source ranges.
  • donner/svg/components/style/tests/StyleSystem_tests.cc: selector tracing and source-backed matched rule behavior.