gitoria
All repositories: gitoria
6.4 KB
# Differ from custom-ide — reuse assessmentResearch for ticket [gitoria.worldapi.org#2](https://tickets.worldapi.org/projects/gitoria.worldapi.org/2).Source inspected: `loreana:/media/STORAGE/projects/custom-ide` (renderer, vanilla JS + vendoredCodeJar, no framework), specifically `renderer/src/features/{editor,diff-review,hybriel}` and`docs/editor-split-and-diff.md` (the design log for the diff feature, approved 2026-07-30).## What the "differ" actually isNot one file — five pieces, ~3,400 LOC total, built up over several phases (see the design log):| Piece | File | LOC | DOM? ||---|---|---|---|| Diff algorithm | `editor/lineDiff.js` | 249 | **No** — pure, aligns two texts into rows (patience-diff anchors + LCS fallback, `MAX_LCS_CELLS` guard) || Live gutter bars | `editor/editorChangeBars.js` | 75 | No — reuses `lineDiff` || Diff widget shell | `diff-review/DiffReviewWidget.js` | 302 | Yes — two `EditorSurface`s side by side || Editor surface (gutter, spacers, highlight, scroll) | `editor/EditorSurface.js` | 614 | Yes, heavily || Canvas minimap | `editor/EditorMinimap.js` | 628 | Yes (canvas) || Syntax highlighters (per language, regex-based) | `editor/editorHighlighter.js` | 1,027 | No || Vendored editing library | `vendor/codejar.js` (npm `[email protected]`, MIT) | 499 | Yes |`EditorWidget.js` itself (2,770 LOC) is mostly file/LSP/dirty-tracking plumbing the differ doesn'tneed — excluded above.## Reusability, piece by piece**`lineDiff.js` — yes, directly.** Zero DOM dependency (the code comments say so explicitly: keptseparate *because* importing it into the widget would have dragged in CodeJar, which needs a`window`). It has its own Node smoke test. This is the actual "differ" and is the easiest, highest-valuepiece to make a shared component: a worldapi-wide `differ` module, callable from any project(gitoria diffs, but also e.g. a future review UI), with no browser coupling at all.**`editorHighlighter.js` — yes, and partly done already.** custom-ide already ships a **Hybrielsyntax highlighter** at `renderer/src/features/hybriel/highlight.js` (regex tokenizer overHybriel's keyword/type/operator set, ~70 LOC, no dependencies) — written for its own use, butdirectly reusable verbatim for `.hl` files in gitoria's diff/editor views.**CodeJar + `EditorSurface` + `EditorMinimap` — a large piece (not "easily rewritable") — to be ported natively.**This is where the ticket's premise ("codejar is quite simple and probably easily rewritable inhybriel") undersells the actual scope. CodeJar itself is small (499 LOC, MIT, plain`contenteditable` + `Range` API) and easy to read. But the feature built on top of it is not simple:the design log documents real trial-and-error to get there —- diff alignment uses `contenteditable="false"` DOM "spacer" elements inserted via `Range` (notblank text lines), so the editable side's `getCode()` stays byte-identical to the real file;- spacers must be re-inserted after **every** re-highlight because CodeJar rewrites `innerHTML`each time, or the two sides drift a line apart;- line-highlight bands are positioned from `getComputedStyle` line-height, deferred via`ResizeObserver` because a detached element reports no real metrics;- the minimap is a hand-rolled canvas renderer with its own tokenizer-output reuse, viewport slider,and marker ruler.None of that complexity is intrinsic to codejar — it's what "diff editor with a minimap, gutter,and an editable proposal side" costs regardless of implementation language.## Would a native Hybriel rewrite work today?Judged against the open Hybriel tickets already known to this project (see the worker brief's list),several are direct blockers for exactly this feature, not incidental:- **hybriel#32** (`hl:webex` re-creates elements, incl. `script src`, when an `if` in the same Viewflips) — the diff widget's "changed only" toggle and the read-only/editable swap are preciselythis pattern: conditional re-render of a live editing surface, which would blow away CodeJar'sDOM/caret state on every toggle if View re-creates the node.- **hybriel#33** (no conditional boolean attributes) — `contenteditable`/`aria-readonly` areboolean-attribute toggles core to `EditorSurface.setReadOnly()`.- **hybriel#31** (no custom DOM event binding) — CodeJar communicates through its own `onUpdate`callback and native `input`/`keydown` handling, not a framework event system; a native port needsa way to hand webex an escape hatch into the raw DOM.- **hybriel#17** (`if (!member)` renders nothing) and **hybriel#9** (manifest statics unreadable intheir own function routes) are the kind of "silent wrong render" bugs that are expensive to debuginside something this DOM-fiddly.None of these make a Hybriel differ *impossible* — but they make a **from-scratch native rewrite ofthe editing surface** premature until webex's conditional-rendering and DOM-event story is solid.The diff *algorithm* has no such dependency and is unaffected.## Recommendation (final, after gitoria#4)The creator rejected the JS-asset route: no foreign bundle is embedded. The plan is native Hybriel only:1. **Differ algorithm first** — port `lineDiff.js` (pure, 249 LOC, no DOM) as a native Hybriel module inlayouts.worldapi.org (shared components live there, gitoria#3). Unblocked; needs a ticket in that project.2. **Editing surface** — build natively (spacers, re-highlight, contenteditable toggling, custom DOMevents). Blocked on hybriel#31/#32/#33/#17 (and #41); fix or work around those in Hybriel itself.The custom-ide code stays a reference for the behaviours to reproduce.(An earlier "tier 1: ship the existing JS as a client asset" recommendation was removed; it is rejected.)## Questions- ~~Where should the `differ` module live?~~ Decided by the creator (gitoria#3): shared components(editor, differ, comments, design tokens) live in **layouts.worldapi.org**, not in gitoria and notin a separate project.- ~~Embed custom-ide's CodeJar bundle as a static JS asset for now?~~ **Rejected by the creator(gitoria#4):** the original ticket (#2) already answered it — editor and differ are to be built asreusable **native Hybriel components** in layouts.worldapi.org, not embedded as a foreign JS bundle.Do not build the JS-asset route.Remaining work is the native port (differ algorithm first — unblocked; editing surface — see theopen Hybriel tickets #31/#32/#33/#17 above, which must be fixed or worked around in Hybriel itself).
Branches
- mainmain branch