Contribute rewrite Phase 1: CM6 markdown source editor
Swap the Contribute-mode editing surface from Tiptap WYSIWYG to a CodeMirror 6 markdown source editor. Discuss mode and any read-only viewing continues to render through Tiptap. The §8.11 manual-edit debounce now reads the raw markdown source via CodeMirror's doc, eliminating the lossy `editor.getText()` round-trip that RFCView.jsx flagged as a §19.2 candidate; what the contributor typed is exactly what gets POSTed to manual flush. The §8.10 paragraph-margin gutter accent on Tiptap is dropped — it was dead in read-only Discuss anyway, and Phase 4 of the Contribute rewrite adds a change-anchored gutter against the CM6 raw pane. The Tiptap-side accept-time injection of <span class="tracked-*"> markup also drops out — CM6 can't render those spans, and Phase 3's preview pane is the proper home for tracked changes. The reviewMode / DiffView toggle still works against marked-rendered HTML in the interim until Phase 7 retires it. Notes: - Bundle gzipped grows ~50KB for CM6 modules (state/view/commands/ language/lang-markdown). Mermaid in Phase 2 will be the larger lift and should lazy-load. - Verified the CM6 editor mounts cleanly via Vite dev preview: ref handle (`view/getDoc/setDoc`) is wired, `onUpdate` fires on doc changes, gutter / line-numbers / active-line all render, and the source round-trips verbatim. Could not drive the full RFCView Contribute flow end-to-end without a running backend; the manual countdown + save-now + accept/decline pathways are verified by inspection only. - 125 backend integration tests still green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+26
-12
@@ -1,4 +1,4 @@
|
||||
/* Adapted from the prototype's App.css per §18, narrowed to slice-1 surfaces. */
|
||||
/* App.css — narrowed to slice-1 surfaces. */
|
||||
|
||||
.boot {
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
@@ -441,13 +441,6 @@
|
||||
.editor-content .tiptap ul, .editor-content .tiptap ol { padding-left: 24px; }
|
||||
.editor-content .tiptap code { background: #f0f0ee; padding: 1px 5px; border-radius: 3px; font-size: 13px; }
|
||||
|
||||
.editor-content .tiptap .paragraph-changed {
|
||||
border-left: 3px solid #f59e0b;
|
||||
padding-left: 10px;
|
||||
margin-left: -13px;
|
||||
background: linear-gradient(to right, #fffbeb 0%, transparent 60%);
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
.editor-content .tiptap .selection-highlight {
|
||||
background: rgba(99, 102, 241, 0.15);
|
||||
border-radius: 2px;
|
||||
@@ -463,6 +456,27 @@
|
||||
border-radius: 2px; padding: 1px 2px; cursor: pointer;
|
||||
}
|
||||
|
||||
/* CodeMirror 6 source editor (Contribute mode). */
|
||||
.cm-source-editor {
|
||||
flex: 1; min-height: 0;
|
||||
display: flex; flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.cm-source-editor .cm-editor {
|
||||
flex: 1; min-height: 0;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
|
||||
font-size: 13px; line-height: 1.6;
|
||||
background: #fff;
|
||||
}
|
||||
.cm-source-editor .cm-editor.cm-focused { outline: none; }
|
||||
.cm-source-editor .cm-scroller { padding: 24px 0; }
|
||||
.cm-source-editor .cm-content { padding: 0 32px; max-width: 880px; }
|
||||
.cm-source-editor .cm-gutters {
|
||||
background: #fafafa; border-right: 1px solid #f0f0ee; color: #b0b0b0;
|
||||
}
|
||||
.cm-source-editor .cm-activeLineGutter { background: #f3f4f6; color: #555; }
|
||||
.cm-source-editor .cm-activeLine { background: #fafbfc; }
|
||||
|
||||
.readonly-bar {
|
||||
border-top: 1px solid #e5e5e5;
|
||||
padding: 10px 16px; text-align: center;
|
||||
@@ -1236,8 +1250,8 @@
|
||||
color: #fbbf24; /* admin link sits a notch warmer to signal authority */
|
||||
}
|
||||
|
||||
/* /philosophy — the §14.2 read surface. The body inherits the
|
||||
prototype's markdown styling; the header is a thin chrome strip. */
|
||||
/* /philosophy — the §14.2 read surface. The body uses the shared
|
||||
markdown styling; the header is a thin chrome strip. */
|
||||
.chrome-pane {
|
||||
flex: 1; min-width: 0; overflow: auto;
|
||||
padding: 0; background: #fff;
|
||||
@@ -1298,8 +1312,8 @@
|
||||
}
|
||||
|
||||
/* Richer landing page (§14.1) — adds the three-item deck under the
|
||||
pitch. The .landing container's flex centering stays from the
|
||||
prototype; the new content lives inside .landing-inner. */
|
||||
pitch. The .landing container handles flex centering; the new
|
||||
content lives inside .landing-inner. */
|
||||
.landing-inner {
|
||||
max-width: 620px;
|
||||
display: flex; flex-direction: column; align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user