Skip to content

Refactor version comparison - #9293

Open
mejo- wants to merge 14 commits into
mainfrom
refactor/version-comparison
Open

mejo- wants to merge 14 commits into
mainfrom
refactor/version-comparison

Conversation

@mejo-

@mejo- mejo- commented Sep 28, 2026

Copy link
Copy Markdown
Member

📝 Summary

Follow-up to #9050

This replaces the Markdown version comparison added in #9050 with a smaller implementation that is easier to maintain.

  • New comparison model in src/comparison/compare.ts; the comparison views are rebuilt on top of it.
  • Opening "Compare" in the Viewer now shows the new diff comparison, starting with the full documents view. Fixes Version difference extraction #4422.
  • In the documents view, matching blocks line up side by side, and both panes scroll together.
  • Comparing one saved version with another saved version now works.
  • The Viewer's loading spinner no longer stays visible after starting a comparison.

Deliberately left out, to keep the scope small:

  • the Markdown source view
  • detection of moved blocks
  • changes to the Viewer API (the Viewer integration stays inside Text)

The comparison-only options added to the shared editor extensions (RichText, TextDirection) are removed again, so the regular editor is unaffected.

The test suite for the comparison is reduced to focused unit tests for the model, alignment, decorations and components; the separate Playwright comparison harness is removed.

🖼️ Screenshots

🏚️ Before 🏡 After
image image

🏁 Checklist

  • Code is properly formatted (npm run lint / npm run stylelint / composer run cs:check)
  • Sign-off message is added to all commits
  • Tests (unit, integration and/or end-to-end) passing and the changes are covered with tests

🤖 AI (if applicable)

  • The content of this PR was partly or fully generated using AI tools
  • The AI-generated content was reviewed, comprehended and tested by a human

@mejo- mejo- self-assigned this Sep 28, 2026
@mejo- mejo- added the enhancement New feature or request label Sep 28, 2026
@mejo- mejo- changed the title Refactor/version comparison Refactor version comparison Sep 28, 2026
@mejo-
mejo- force-pushed the refactor/version-comparison branch from 1ed09b1 to 5533cfb Compare September 28, 2026 17:27
The comparison Playwright suite did not exercise the app. It loaded the
login page, injected the built bundle, replaced the document body and
mounted the comparison factory directly, with patched observers and
forced failures. It needed three extra Playwright projects, an
environment switch in the config, a unit test of that config and the
axe-core dependency.

Remove it along with the config and workflow changes it required. The
comparison gets a real end-to-end test through the Viewer version
comparison in a later commit.

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5.5
The literal source comparison ran a line diff in a module worker with
cancellation, gap paging, word-level emphasis under time budgets and
visible tokens for control characters and line endings. That is a lot
of machinery for a view the rendered comparison rarely needs.

Remove the view, its worker and the worker build config. The plain
source fallback stays for the case where no rendered comparison can be
built; it now shows both snapshots verbatim without display limits.

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5.5
Add compareDocuments, which aligns sibling nodes with an array diff on
node equality, pairs the differing nodes positionally and compares
paired textblocks with prosemirror-changeset. Attribute changes are
reported for a small set of known attributes, everything else is text,
formatting or structure.

The accompanying decoration plugin highlights one side of the changes
and the editor helper loads content through setContent so text
direction is inferred like in every other editor.

This does not replace the existing model yet; the components move over
in the next commit.

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5.5
Rewrite MarkdownContentComparison and ComparisonChangeList on top of
compareDocuments and remove the previous model, its presentation
helpers and their tests.

The change list groups rows by the nearest heading and shows a label
with before and after previews. The document panes highlight the
changes through the decoration plugin, scroll to the current change
and stack below 760px through a container query instead of a resize
observer. The factory mounts the component and returns a destroy
handle; a failing or oversized comparison falls back to plain source.

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5.5
The comparison editors no longer need special treatment in RichText:
they load content through setContent, so the text direction plugin
infers paragraph direction like everywhere else, and duplicate heading
anchors in two read-only panes are harmless. Keymap and Search do
nothing in a non-editable editor, so registering them unconditionally
restores the previous behaviour for RichTextReader as well.

Inline the Markdown rendering helper into useEditorMethods again, as
nothing else uses it.

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5.5
Viewer's "Compare to current version" renders Text's viewer component
for the older version next to the current file. For Markdown files the
older version's component now loads both versions and shows the
comparison instead, and the sibling pane with the current file's editor
is hidden. Plain text files keep the side-by-side view.

Adjust the versions end-to-end test to expect the comparison.

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5.5
Reviewers want to see the documents side by side before drilling into
the list of changes.

Fixes: #4422

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5.5
Pair the top-level blocks of both documents, measure their rendered
offsets and pad the side whose block sits higher with a widget
decoration, so unchanged content stays level across the two panes
even when blocks were inserted or removed. Measuring includes the
spacers already in place, so a second round settles margin effects.
The panes re-align on resize and after images load.

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5.5
Mirror the scroll offset between the two panes, which line up block
by block since the previous commit. Jumping to a change scrolls one
pane and lets the other follow. Smooth scrolling is dropped because
mirroring an animated scroll feeds intermediate positions back.

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5.5
Viewer creates a new file object when the same file is opened again,
which happens when a version comparison starts, and the new object
starts with loaded set to false. The component is kept because its key
is unchanged, so nothing reported loaded again and the loading spinner
stayed on top of the comparison. Watch the flag passed by Viewer and
report loaded once more when it drops after the content has loaded.

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5.5
Spacers picked up the editor's styling for divs and could not render
below 34px, so small corrections never settled. Images that appear
after loading also grew a table after the last alignment. Reset the
spacer box and re-align whenever either document's size changes.

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5.5
Fixes version comparison in Collectives app.

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5.5
The border now uses the color of the change type: green for added, red
for removed, orange for attribute changes. This also fixes attribute
changes on blocks, where the neutral border overrode the orange
underline.

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5.5
Aligning blocks by equality alone picks arbitrary matches among
similar-looking paragraphs, so a paragraph split around an image
showed up as one paragraph added and others removed.

Blocks that are equal and unique on both sides anchor the alignment.
The blocks between two anchors are paired by text similarity, shared
words or a shared start and end, so edited and split paragraphs pair
with their origin. This replaces the array diff, so the diff package
is no longer needed.

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5.5

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: 👀 In review

Development

Successfully merging this pull request may close these issues.

Version difference extraction

1 participant