Commit Graph

3 Commits

Author SHA1 Message Date
b7360dd48e Recognize Markdown tables on paste and while typing (#339)
Some checks failed
CI / Lint, typecheck, test (pull_request) Failing after 2m6s
CI / Auth e2e pack (pull_request) Has been skipped
CI / Import/export fidelity gate (pull_request) Has been skipped
CI / Build container images (pull_request) Has been skipped
The paste conversion (issue #30) already handled tables, but any
text/html flavor on the clipboard bypassed it. Code editors (VS Code
with copyWithSyntaxHighlighting) ship the plain text a second time as
styled div/span HTML, so a Markdown table copied there arrived verbatim
while the same text from a plain editor converted fine. Clipboard HTML
without a single structural element (table/list/heading/link/emphasis/
code...) is now treated as equivalent to the plain text; anything from a
rich-text source keeps going through ProseMirror's HTML paste.

Pasting inside a code block never converts anymore -- text is code
there, and the conversion would have split the block around rich nodes.

Hand-typed tables: pressing Enter at the end of a GFM separator row
whose previous sibling is a pipe row replaces the two paragraphs with a
real table (input rules cannot express this -- they see only one
textblock). Conversion is refused inside existing tables; body rows are
then typed cell-wise, with Tab appending rows (#338).

Closes #339

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aoPvnakfBP28nAfijgUY9
2026-08-15 21:12:00 +02:00
33121cd73d Move pond settings to a TopBar gear, pin the trash link to the sidebar bottom (M10 follow-up)
All checks were successful
CD / Build and push images (push) Successful in 1m8s
CD / Deploy to Test (push) Successful in 11s
CD / Smoke tests against Test (push) Successful in 1m11s
CD / Promote to Int (push) Successful in 10s
CI / Lint, typecheck, test (push) Successful in 3m42s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 5m31s
CI / Import/export fidelity gate (push) Successful in 47s
- owners get a Settings icon next to the pond name while a pond route
  is active (same lucide set, localized aria-label/tooltip via the
  existing labels:link key); gone on non-pond routes and for non-owners
- the trash stays a text link but pins to the sidebar's bottom
  (.sidebar is a flex column now; .sidebar__footer uses margin-top:auto)
- trash.spec: delete flows go through the #101 overflow menu (was
  missed in 65f30a5 — the pack is not part of CI)
- markdown.spec: replace the wait for the 'saved' status removed in #36
  with polling the export endpoint (pre-existing local failure, same
  category as the known image.spec one)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1
2026-07-12 06:07:15 +02:00
c9011cb44f Add Markdown copy, paste, and per-page export endpoint (#30)
All checks were successful
CD / Build and push images (push) Successful in 2m3s
CI / Lint, typecheck, test (push) Successful in 1m41s
CI / Auth e2e pack (push) Successful in 1m46s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 8s
CD / Smoke tests against Test (push) Successful in 1m10s
CD / Promote to Int (push) Successful in 10s
Wires docToMarkdown/markdownToDoc into the editor clipboard: copying
selected content puts Markdown on text/plain alongside the browser's
own HTML (so pasting into a plain-text destination yields Markdown),
and pasting plain text that looks like a Markdown document converts it
to rich nodes; content with real HTML on the clipboard is left to
ProseMirror's normal HTML-based paste, and the heuristic requires two
or more distinct Markdown-shaped lines (or a fenced code block) so
ordinary prose is never mangled.

Both directions need the parsed/selected doc re-hydrated against
whichever schema instance is on the other side of the boundary: the
canonical editorSchema (packages/shared) for markdownToDoc's output
before inserting it into the live view, and the live view's schema
wrapped back into editorSchema before handing a slice to docToMarkdown
— they're structurally identical but not the same object, and
ProseMirror's content checks are identity-based.

Adds GET /pages/:id/export/markdown (downloads <slug>.md), serving the
already-derived page_content_cache.markdown (#23) rather than
re-decoding the Yjs state. "Copy as Markdown" and "Download as
Markdown" actions in the page header both read from that same
endpoint, so they always agree with each other and with the last saved
state.

Closes #30
2026-07-08 12:05:11 +02:00