Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditionally-rendered block replace decoration breaks selection rendering and gutter #1406

Closed
jsimonrichard opened this issue Jul 12, 2024 · 9 comments

Comments

@jsimonrichard
Copy link

Describe the issue

I'm trying to create a block replace decoration that is not displayed when the editor selection includes that decoration's range so that the user can edit the text behind the decoration. However, this is causing some issues with the rendering of the selection and the gutter.

I've created an MRE: https://github.com/jsimonrichard/codemirror-block-deco-issue (I've included a CodeMirror sandbox link below as well).

As shown in the video below, It seems works at first, but as soon as you make an edit to the second or third line the line number next to the decoration disappears. If you try to edit the text behind the decoration, you can, but you can't see any of the selections you make. Selection still works (in the video I double click to select the word "Hello" and then hit backspace to delete the entire word) but it's not displayed. But, if you edit the text covered by the decoration, the line number comes back and selection works as normal.

codemirror-block-decoration-issue.mp4

Browser and platform

I've tested Brave, Chrome, and Firefox

Reproduction link

https://codemirror.net/try/?c=aW1wb3J0IHtiYXNpY1NldHVwLCBFZGl0b3JWaWV3fSBmcm9tICJjb2RlbWlycm9yIgppbXBvcnQge2phdmFzY3JpcHR9IGZyb20gIkBjb2RlbWlycm9yL2xhbmctamF2YXNjcmlwdCIKaW1wb3J0IHsgRWRpdG9yU3RhdGUsIFN0YXRlRmllbGQgfSBmcm9tICJAY29kZW1pcnJvci9zdGF0ZSIKaW1wb3J0IHsgRGVjb3JhdGlvbiwgV2lkZ2V0VHlwZSB9IGZyb20gIkBjb2RlbWlycm9yL3ZpZXciCgpjbGFzcyBNeVdpZGdldCBleHRlbmRzIFdpZGdldFR5cGUgewogIHRvRE9NKCkgewogICAgbGV0IGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CiAgICBlbC5pbm5lckhUTUwgPSAiSGVsbG8gd29ybGQhIChpdCdzIGEgd2lkZ2V0KSI7CiAgICByZXR1cm4gZWw7CiAgfQp9Cgpjb25zdCBidWlsZERlY29zID0gKHN0YXRlKSA9PiB7CiAgY29uc3QgZGVjb3MgPSBbXTsKICBjb25zdCBsaW5lID0gc3RhdGUuZG9jLmxpbmUoMSk7CiAgCiAgaWYgKHN0YXRlLnNlbGVjdGlvbi5yYW5nZXNbMF0uZnJvbSA8IGxpbmUudG8pCiAgICByZXR1cm4gRGVjb3JhdGlvbi5ub25lOwoKICByZXR1cm4gRGVjb3JhdGlvbi5zZXQoWwogICAgRGVjb3JhdGlvbi5yZXBsYWNlKHsKICAgICAgd2lkZ2V0OiBuZXcgTXlXaWRnZXQoKSwKICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICBibG9jazogdHJ1ZSwKICAgIH0pLnJhbmdlKGxpbmUuZnJvbSwgbGluZS50byksCiAgXSk7Cn07CgpleHBvcnQgY29uc3QgZGVjb3NFeHRlbnNpb24gPSBTdGF0ZUZpZWxkLmRlZmluZSh7CiAgY3JlYXRlKHN0YXRlKSB7CiAgICByZXR1cm4gYnVpbGREZWNvcyhzdGF0ZSk7CiAgfSwKICB1cGRhdGUoZGVjbywgdHIpIHsKICAgIGlmICh0ci5zZWxlY3Rpb24gfHwgdHIuZG9jQ2hhbmdlZCkKICAgICAgZGVjbyA9IGJ1aWxkRGVjb3ModHIuc3RhdGUpOwogICAgcmV0dXJuIGRlY28ubWFwKHRyLmNoYW5nZXMpOwogIH0sCiAgcHJvdmlkZTogZiA9PiBFZGl0b3JWaWV3LmRlY29yYXRpb25zLmZyb20oZiksCn0pOwoKCm5ldyBFZGl0b3JWaWV3KHsKICBkb2M6ICJjb25zb2xlLmxvZygnaGVsbG8nKVxuIiwKICBleHRlbnNpb25zOiBbYmFzaWNTZXR1cCwgamF2YXNjcmlwdCgpLCBkZWNvc0V4dGVuc2lvbl0sCiAgcGFyZW50OiBkb2N1bWVudC5ib2R5Cn0pCg==

@marijnh
Copy link
Member

marijnh commented Jul 14, 2024

I don't ever see the line number next to the widget. How are you getting in a state where that is displayed?

@jsimonrichard
Copy link
Author

I'm not sure; I noticed that the number only appears when the decoration is on the first line and when the decoration is displayed conditionally (based on the selection). Also, when the decoration takes up two lines, neither of the bugs occur.

But you should be able to reproduce what I have using either of the examples I've provided. By "I don't ever see..." do you mean that my examples aren't working?

@jsimonrichard
Copy link
Author

I don't know if this gives you any clues, but I wasn't able to reproduce the bug when using the bundled version of a library containing this logic. I'm using vite with this config:

// vite.config.js
...

export default defineConfig({
  ...
  build: {
    lib: {
      // Could also be a dictionary or array of multiple entry points
      entry: resolve(__dirname, 'lib/main.ts'),
      name: 'HyperMD',
      formats: ['es', 'cjs'],
      // the proper extensions will be added
      fileName: (format, entryName) => `${entryName}.${format}.js`,
    },
    rollupOptions: {
      external: [
        '@codemirror/state',
        '@codemirror/view',
        '@codemirror/commands',
        '@codemirror/language',
        '@codemirror/lang-markdown',
        '@codemirror/language-data',
        '@lezer/highlight',
      ],
    },
  },
});

@marijnh
Copy link
Member

marijnh commented Jul 16, 2024

By "I don't ever see..." do you mean that my examples aren't working?

I mean I never see a line number next to the widget (and that is the expected behavior).

@jsimonrichard
Copy link
Author

Hmm... maybe it's a browser specific thing (regardless, it's not a high priority for me; I don't need line numbers right now). Are you able to reproduce the other part of the bug?

@marijnh
Copy link
Member

marijnh commented Jul 18, 2024

No, I'm not. I tried both Chrome and Firefox. Both seem to behave normally for selections and edits on the first line.

@jsimonrichard
Copy link
Author

On this version of Chrome, I'm able to reproduce both bugs

Google Chrome	126.0.6478.126 (Official Build) (64-bit) 
Revision	d36ace6122e0a59570e258d82441395206d60e1c-refs/branch-heads/6478@{#1591}
OS	Linux
JavaScript	V8 12.6.228.21
User Agent	Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
Command Line	/usr/bin/google-chrome-stable --flag-switches-begin --flag-switches-end --origin-trial-disabled-features=ElementCapture
Executable Path	/opt/google/chrome/google-chrome

Using this version of Firefox I'm able to reproduce both bugs, but only after adding a new line to the document (just adding a space won't do it). And the gutter number works as expected until the new line is added.

128.0 (64-bit)
Mozilla Firefox Snap for Ubuntu
canonical-002 - 1.0

Also, I was able to reproduce this on both Linux (Kubuntu 22.04.3 LTS x86_64) and Windows 11, so I doubt it's OS dependent.

While doing testing, I realized I missed a detail of this bug. When the decoration is not displayed (when the cursor is on the first line), the first gutter number is still not displayed. Except in firefox before a new line is added; then the gutter number appears/disappears as expected.

marijnh added a commit to codemirror/view that referenced this issue Jul 29, 2024
FIX: Fix an issue where `EditorView.viewportLineBlocks` (and thus other things like
the gutter) might be out of date after some kinds of decoration changes.

Issue codemirror/dev#1406
@marijnh
Copy link
Member

marijnh commented Jul 29, 2024

Right, I can see it behaving weirdly that way. This was an update issue where some parts of the view state didn't get recomputed though they should, for decoration changes like that, even if the resulting block heights didn't change. Attached patch should help with that.

Can we close this or are you are of remaining problems?

@jsimonrichard
Copy link
Author

I just verified---it's working for me now too.

That's all I had it. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants