Repository navigation
[stable35] Refactor version comparison - #9386
Open
backportbot[bot] wants to merge 19 commits into
Open
backportbot[bot] wants to merge 19 commits into
backportbot[bot] wants to merge 19 commits into
Conversation
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
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
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
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
Signed-off-by: Jonas <jonas@freesources.org> Assisted-by: ClaudeCode:claude-opus-5-5
Each node is fingerprinted at most once per comparison, and the after document is rebuilt on every call, so the fingerprint cache never got a hit. Compute the fingerprint directly instead. Also replace code for "middle between two numbers rounded down" with an alternative that's easier to parse. Also add better documentation to some functions. Signed-off-by: Jonas <jonas@freesources.org> Assisted-by: ClaudeCode:claude-opus-5-5
Introduce a Gap type and gapsBetween() so alignChildren() and compareChildren() share one definition of the unmatched children between matches, instead of each tracking positions by hand with a sentinel match. Split similarity() into sharedWords() and sharedEdges(). Describe the anchor and gap steps in compareDocuments() and clarify the ChangeCategory and MIN_SIMILARITY comments. Signed-off-by: Jonas <jonas@freesources.org> Assisted-by: ClaudeCode:claude-opus-5-5
Move what the views of a comparison share out of MarkdownContentComparison into a comparison session: the editors of both sides, the changes, the current one and the formatting filter, and the alignment and synchronised scrolling of the documents. The document of each side, the filter, the change navigation and the list of changes become components of their own working on a session, so the two documents can also be shown by different components. MarkdownContentComparison is built from these parts and behaves as before. Signed-off-by: Jonas <jonas@freesources.org> Assisted-by: ClaudeCode:claude-opus-5-5
A spacer element of the needed height before a block stopped the block's top margin from collapsing with the bottom margin above it, so the block moved by the spacer plus the smaller margin. Where that margin was larger than the correction, typically before a heading, the documents never lined up: each round overshot and the next corrected on the other side, and the panes kept jumping. Set the block's top margin to the measured gap above it plus the spacer instead. The margins still collapse, and the block moves by exactly the spacer. Signed-off-by: Jonas <jonas@freesources.org> Assisted-by: ClaudeCode:claude-opus-5-5
mejo-
force-pushed
the
backport/9293/stable35
branch
from
October 14, 2026 13:26
996ae45 to
44c4e54
Compare
mejo-
marked this pull request as ready for review
October 14, 2026 13:26
mejo-
approved these changes
Oct 14, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport of #9293
Warning, This backport had conflicts that were resolved with the⚠️
oursmerge strategy and is likely incompleteTodo
Learn more about backports at https://docs.nextcloud.com/server/stable/go.php?to=developer-backports.