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

Deleting parent list leaves nested lists orphaned #4230

Open
raghavsethi opened this issue May 30, 2024 · 2 comments
Open

Deleting parent list leaves nested lists orphaned #4230

raghavsethi opened this issue May 30, 2024 · 2 comments

Comments

@raghavsethi
Copy link

Steps for Reproduction

  1. Visit empty playground
  2. Create nested list with at least two levels
  3. Delete the first level

Expected behavior:

The remaining levels should dedent when their parent is deleted.

Here is an extremely hacky demonstration of what the behavior should be.

Actual behavior:

The remaining levels are orphaned (i.e. are indented as if they are nested one level deeper than they are).

Version:

2.0.2

Request

I realize that nested lists are a long-running source of interesting behavior, so I don't actually expect this to be fixed. However, this behavior is important to my use case so I'd love some advice on how to achieve this. I have a super hacky implementation below, and it's kinda wild that updating the class names actually causes Quill to generate the right deltas - so I'd love to know what the 'canonical' way of doing something like this would be.

Here's the working demo.

class ListDedentModifier {
    constructor(quill) {
        this.quill = quill;
        this.quill.on("text-change", this.onTextChange.bind(this));
    }

    onTextChange(delta) {
        for (const op of delta.ops) {
            if (op.attributes && op.attributes.list === null) {
                const cursorStart = this.quill.getSelection().index;
                const [line] = this.quill.getLine(cursorStart);
                const next = line.next;
                for (const child of next.domNode.childNodes ?? []) {
                    const className = child.className;
                    const indentMatch = className.match(/ql-indent-(\d+)/);
                    const currentIndentLevel = parseInt(indentMatch[1], 10);
                    const newIndentLevel = Math.max(0, currentIndentLevel - 1);
                    child.className = `ql-indent-${newIndentLevel}`;
                }
            }
        }
    }
}

Quill.register("modules/listModifier", ListDedentModifier);
@luin
Copy link
Member

luin commented May 31, 2024

I would do something pretty similar but one missing case in your demo is deleting. Also instead of updating class names directly, you could go with quill.updateContents() to update the contents directly.

@raghavsethi
Copy link
Author

@luin Thanks for the response, would you mind helping me understand how to use updateContents to achieve this? It seems pretty challenging to go from a tree of Blot nodes to deltas that apply on positions. IIUC the hard bit is that you have to construct a delta for each list item (which can be further nested) since each item is on a different line.

I'm happy to go read a bunch of code and figure it out but some pointers would be pretty helpful!

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

No branches or pull requests

2 participants