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

Todolist lost checked property when reload or set to Source Editing #15602

Closed
woaiiimipi opened this issue Dec 28, 2023 · 6 comments · Fixed by #16785
Closed

Todolist lost checked property when reload or set to Source Editing #15602

woaiiimipi opened this issue Dec 28, 2023 · 6 comments · Fixed by #16785
Labels
domain:ui/ux This issue reports a problem related to UI or UX. package:list support:2 An issue reported by a commercially licensed client. type:bug This issue reports a buggy (incorrect) behavior.

Comments

@woaiiimipi
Copy link

📝 Provide detailed reproduction steps (if any)

When I add todolist to a table cell, I checked the checkbox, and saved the data to server, when I reload the data, the checkbox's checked status is lost.

Before:
image
Reload:
image
Below is my source code, you can copy the code to source editing, the checked="checked" status will be lost

<html><head></head><body>
<figure class="table">
    <table>
        <tbody>
            <tr>
                <td style="background-color:hsl(60, 75%, 60%);text-align:center;">
                    <p style="color:#7F6000;font-family:Calibri;font-size:12.0pt;margin:0in;">
                        <span style="color:hsl(0,0%,0%);"><strong>FOUNDATION</strong></span>
                    </p>
                </td>
            </tr>
            <tr>
                <td style="vertical-align:top;">
                    <ul class="todo-list">
                        <li>
                            <label class="todo-list__label todo-list__label_without-description"><input type="checkbox" checked="checked" disabled="disabled"></label>
                            <p style="font-family:Calibri;font-size:12.0pt;margin:0in;">
                                <strong>Net Worth:&nbsp;</strong>
                            </p>
                        </li>
                    </ul>
                </td>
            </tr>
        </tbody>
    </table>
</figure>
</body></html>

✔️ Expected result

Checked status can reload correctly

❌ Actual result

Checked status is lost.

❓ Possible solution

📃 Other details

  • Browser: Latest Chrome
  • OS: MacOS / Windows
  • First affected CKEditor version: Latest ckeditor version
  • Installed CKEditor plugins:
    "@ckeditor/ckeditor5-alignment": "^40.0.0",
    "@ckeditor/ckeditor5-autoformat": "^40.0.0",
    "@ckeditor/ckeditor5-basic-styles": "^40.0.0",
    "@ckeditor/ckeditor5-block-quote": "^40.0.0",
    "@ckeditor/ckeditor5-cloud-services": "^40.0.0",
    "@ckeditor/ckeditor5-dev-translations": "^32.1.2",
    "@ckeditor/ckeditor5-dev-utils": "^32.1.2",
    "@ckeditor/ckeditor5-editor-classic": "^40.0.0",
    "@ckeditor/ckeditor5-editor-inline": "^40.0.0",
    "@ckeditor/ckeditor5-essentials": "^40.0.0",
    "@ckeditor/ckeditor5-font": "^40.0.0",
    "@ckeditor/ckeditor5-heading": "^40.0.0",
    "@ckeditor/ckeditor5-horizontal-line": "^40.0.0",
    "@ckeditor/ckeditor5-html-support": "^40.0.0",
    "@ckeditor/ckeditor5-image": "^40.0.0",
    "@ckeditor/ckeditor5-indent": "^40.0.0",
    "@ckeditor/ckeditor5-link": "^40.0.0",
    "@ckeditor/ckeditor5-list": "^40.0.0",
    "@ckeditor/ckeditor5-media-embed": "^40.0.0",
    "@ckeditor/ckeditor5-mention": "^40.0.0",
    "@ckeditor/ckeditor5-page-break": "^40.0.0",
    "@ckeditor/ckeditor5-paragraph": "^40.0.0",
    "@ckeditor/ckeditor5-paste-from-office": "^40.0.0",
    "@ckeditor/ckeditor5-source-editing": "^40.0.0",
    "@ckeditor/ckeditor5-special-characters": "^40.0.0",
    "@ckeditor/ckeditor5-table": "^40.0.0",
    "@ckeditor/ckeditor5-theme-lark": "^40.0.0",
    "@ckeditor/ckeditor5-typing": "^40.0.0",
    "@ckeditor/ckeditor5-word-count": "^40.0.0",
    "@ckeditor/ckeditor5-ui": "^40.0.0",
    "@ckeditor/ckeditor5-undo": "^40.0.0",

If you'd like to see this fixed sooner, add a 👍 reaction to this post.

@woaiiimipi woaiiimipi added the type:bug This issue reports a buggy (incorrect) behavior. label Dec 28, 2023
@Witoso Witoso added package:list domain:ui/ux This issue reports a problem related to UI or UX. labels Jan 9, 2024
@niegowski
Copy link
Contributor

Simplest reproduction (with GHS enabled):

<ul class="todo-list">
    <li>
        <label class="todo-list__label todo-list__label_without-description"><input type="checkbox" checked="checked" disabled="disabled"></label>
        <p class="foo">
            foobar
        </p>
    </li>
</ul>

@mabryl mabryl added the support:2 An issue reported by a commercially licensed client. label Feb 19, 2024
@mabryl
Copy link
Contributor

mabryl commented Feb 19, 2024

Also reproducible when changing the alignment on an item in a todo list. Steps to repro:

  1. Create an item in a todo list
  2. Change its alignment, e.g. by centering the text
  3. Check the item on the todo list
  4. Execute editor.setData(editor.getData())

It seems that the checked="checked" attribute goes missing when the text inside the <li> gets wrapped in an additional element, e.g. <p>.

@woaiiimipi
Copy link
Author

Any update? Our clients report this issue again, I think it's an very important function.

@woaiiimipi
Copy link
Author

@niegowski @Witoso @mabryl
Is there any way to avoid it? Too many of our users have encountered this problem.

@illia-stv
Copy link
Contributor

illia-stv commented Jul 23, 2024

As I see it doesn't work with p element, while with span everything works fine (GHS is not required to check it):

<ul class="todo-list">
    <li>
        <label class="todo-list__label todo-list__label_without-description"><input type="checkbox" checked="checked" disabled="disabled"></label>
        <span class="foo">
            foobar
        </span>
    </li>
</ul>

So conversion treats todo list with p element a little bit differently.

This method override data.modelCursor:

private _updateConversionResult( modelElement: ModelElement, data: UpcastConversionData ): void {
const parts = this._getSplitParts( modelElement );
const writer = this.conversionApi.writer!;
// Set conversion result range - only if not set already.
if ( !data.modelRange ) {
data.modelRange = writer.createRange(
writer.createPositionBefore( modelElement ),
writer.createPositionAfter( parts[ parts.length - 1 ] )
);
}
const savedCursorParent = this._cursorParents.get( modelElement );
// Now we need to check where the `modelCursor` should be.
if ( savedCursorParent ) {
// If we split parent to insert our element then we want to continue conversion in the new part of the split parent.
//
// before: <allowed><notAllowed>foo[]</notAllowed></allowed>
// after: <allowed><notAllowed>foo</notAllowed> <converted></converted> <notAllowed>[]</notAllowed></allowed>
data.modelCursor = writer.createPositionAt( savedCursorParent, 0 );
} else {
// Otherwise just continue after inserted element.
data.modelCursor = data.modelRange.end;
}
}

Inside modelCursor we could find an array with 3 elements (first and third elements are empty so they will be removed but they have actual attribute which is responsible for checked property while second doesn't have that attribute but have the text node)

image

First element:

image

Second element:

image

Third element:

image

Meanwhile todo list item with span element have only 1 (with text and attributes), not 3:

image image

Here is a method which remove empty elements (so only second element with text data from the array is left but it doesn't have todo-list-checked attribute) so that the reason of data lost:

private _removeEmptyElements(): void {
let anyRemoved = false;
for ( const element of this._splitParts.keys() ) {
if ( element.isEmpty && !this._emptyElementsToKeep.has( element ) ) {
this.conversionApi.writer.remove( element );
this._splitParts.delete( element );
anyRemoved = true;
}
}
if ( anyRemoved ) {
this._removeEmptyElements();
}
}
}

@illia-stv
Copy link
Contributor

illia-stv commented Jul 23, 2024

Here is example solution: #16785

niegowski added a commit that referenced this issue Aug 5, 2024
Fix (list): A to-do list should preserve the state of the checked items on the data load. Closes #15602.
@CKEditorBot CKEditorBot added this to the iteration 77 milestone Aug 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:ui/ux This issue reports a problem related to UI or UX. package:list support:2 An issue reported by a commercially licensed client. type:bug This issue reports a buggy (incorrect) behavior.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants