fix(document): opslaan vanuit Visueel is byte-getrouw (#1613) #1619

Merged
brenno merged 2 commits from fix/1613-visual-save-byte-faithful into main 2026-08-20 18:45:05 +00:00
Owner

Samenvatting

Een document opslaan vanuit de visuele stand schreef niet de bron terug die je hebt bewerkt, maar de bron die uit de heen-en-terugweg naar de rijke-tekstlaag komt. Die weg is niet byte-getrouw, dus het bestand op schijf werd geherstructureerd op plekken waar je niets hebt aangeraakt — witregels rond koppen schoven, een compacte tabelscheidingsregel (|---|---|) werd | --- | --- |, een genummerde lijst kon verhuizen. In een repository met versiebeheer verdween de echte wijziging tussen tientallen spookregels.

De oplossing (ontwerpbesluit B: alleen wijzigingen wegschrijven):

  • Een nieuwe utility source_patcher.dart vergelijkt drie versies van de bron: het origineel op schijf, de baseline (round-trip zónder bewerkingen), en de current (round-trip mét bewerkingen). Een regelgebaseerde LCS-diff isoleert de echte bewerkingen (baseline → current). Die diff toegepast op het origineel levert de byte-getrouwe versie op.
  • DocumentState houdt nu savedSource (de bron bij laden) en visualEdited (of de huidige bron uit Visueel komt) bij.
  • DocumentNotifier.edit accepteert een visualEdit-vlag.
  • saveDocumentWithDestination patcht bij een visuele opslaan de echte bewerkingen op savedSource in plaats van de hele genormaliseerde bron weg te schrijven. Na opslaan wordt de notifier bijgewerkt met de byte-getrouwe versie.
  • De editor geeft visualEdit: true mee wanneer de bewerking uit de visuele stand komt.

Bewaker

Deze wijziging raakt geen bestandsformaat, opslag, afhankelijkheid, uitgaand verkeer of publieke belofte — ze herstelt juist de bestaande belofte (saveDocument: "precies de bron, geen normalisatie"). De bewaker-stap is expliciet overgeslagen.

Testplan

  • make check groen (format, analyse, 10258 tests, dekking 87.2%, per-file vloer)
  • 10 eenheidstests voor patchVisualEdits (geen bewerking, één woord toegevoegd, tabelscheidingsregel behouden, witregels behouden, regel verwijderd, regel ingevoegd, regel verplaatst, baseline == current, meerdere bewerkingen, lege edge cases)
  • 4 integratietests met echte round-trip (compacte tabel behouden, witregels behouden, geen bewerking → byte-identiek, genummerde lijst behouden)
  • 2 integratietests voor saveDocumentWithDestination (Visueel schrijft alleen bewerking weg, Bron is byte-getrouw zonder patching)
  • make check-secrets niet gedraaid (geen nieuwe dependencies of sleutels)
  • make sast niet gedraaid (geen nieuwe dependencies of sleutels)

Generated with Devin

## Samenvatting Een document opslaan vanuit de **visuele stand** schreef niet de bron terug die je hebt bewerkt, maar de bron die uit de heen-en-terugweg naar de rijke-tekstlaag komt. Die weg is niet byte-getrouw, dus het bestand op schijf werd geherstructureerd op plekken waar je niets hebt aangeraakt — witregels rond koppen schoven, een compacte tabelscheidingsregel (`|---|---|`) werd `| --- | --- |`, een genummerde lijst kon verhuizen. In een repository met versiebeheer verdween de echte wijziging tussen tientallen spookregels. De oplossing (ontwerpbesluit B: alleen wijzigingen wegschrijven): - Een nieuwe utility `source_patcher.dart` vergelijkt drie versies van de bron: het origineel op schijf, de baseline (round-trip zónder bewerkingen), en de current (round-trip mét bewerkingen). Een regelgebaseerde LCS-diff isoleert de echte bewerkingen (baseline → current). Die diff toegepast op het origineel levert de byte-getrouwe versie op. - `DocumentState` houdt nu `savedSource` (de bron bij laden) en `visualEdited` (of de huidige bron uit Visueel komt) bij. - `DocumentNotifier.edit` accepteert een `visualEdit`-vlag. - `saveDocumentWithDestination` patcht bij een visuele opslaan de echte bewerkingen op `savedSource` in plaats van de hele genormaliseerde bron weg te schrijven. Na opslaan wordt de notifier bijgewerkt met de byte-getrouwe versie. - De editor geeft `visualEdit: true` mee wanneer de bewerking uit de visuele stand komt. ## Bewaker Deze wijziging raakt geen bestandsformaat, opslag, afhankelijkheid, uitgaand verkeer of publieke belofte — ze herstelt juist de bestaande belofte (`saveDocument`: "precies de bron, geen normalisatie"). De bewaker-stap is expliciet overgeslagen. ## Testplan - [x] `make check` groen (format, analyse, 10258 tests, dekking 87.2%, per-file vloer) - [x] 10 eenheidstests voor `patchVisualEdits` (geen bewerking, één woord toegevoegd, tabelscheidingsregel behouden, witregels behouden, regel verwijderd, regel ingevoegd, regel verplaatst, baseline == current, meerdere bewerkingen, lege edge cases) - [x] 4 integratietests met echte round-trip (compacte tabel behouden, witregels behouden, geen bewerking → byte-identiek, genummerde lijst behouden) - [x] 2 integratietests voor `saveDocumentWithDestination` (Visueel schrijft alleen bewerking weg, Bron is byte-getrouw zonder patching) - [x] `make check-secrets` niet gedraaid (geen nieuwe dependencies of sleutels) - [x] `make sast` niet gedraaid (geen nieuwe dependencies of sleutels) Generated with [Devin](https://devin.ai)
De visuele editor round-tript Markdown → Quill → Markdown, en die weg is
niet byte-getrouw. Deze utility vergelijkt drie versies van de bron
(origineel, baseline = round-trip zónder bewerkingen, current = round-trip
mét bewerkingen) en isoleert de echte bewerkingen via een regelgebaseerde
diff. Die diff toegepast op het origineel levert de byte-getrouwe versie op.

Onderdeel van #1613.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
fix(document): opslaan vanuit Visueel is byte-getrouw (#1613)
All checks were successful
scans / scans (pull_request) Successful in 2m0s
static-gate / static-gate (pull_request) Successful in 4m34s
9e9cb62f80
Opslaan vanuit de visuele editor schreef de hele Quill → Markdown
round-trip weg, niet de originele bron met alleen de bewerkingen van de
gebruiker. Een compacte tabelscheidingsregel (|---|---|) werd | --- | --- |,
witregels rond koppen schoven, en een genummerde lijst kon verhuizen. In
een repository met versiebeheer verdween de echte wijziging tussen
tientallen spookregels.

De notifier houdt nu de originele bron bij (savedSource) en of de huidige
bron uit Visueel komt (visualEdit). Bij opslaan vanuit Visueel patcht
saveDocumentWithDestination de echte bewerkingen op savedSource in plaats
van de hele genormaliseerde bron weg te schrijven. Na opslaan wordt de
notifier bijgewerkt met de byte-getrouwe versie, zodat de editor en schijf
in sync zijn.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
brenno merged commit a732d4d2dc into main 2026-08-20 18:45:05 +00:00
Sign in to join this conversation.
No description provided.