Cannot have div tags inside columns in CKEditor 5

Created on 18 April 2024, 2 months ago

Problem/Motivation

Any div tag inside columns will be upcasted into a bsGridCol model, and it will therefore be moved up to be a child of the row.

This is resulting in an unexpected structure when switching from source editing to wysiwyg.

Steps to reproduce

  1. With a fresh Drupal 10.2.5 installation
  2. Install the module
  3. Add the plugin to "Full HTML" text format
  4. Add or edit any node using "Full HTML" text format
  5. Use the plugin to create a two columns grid (same result for any number of columns)
  6. Switch to source editing mode
  7. Insert a div inside any of the columns
    You can also paste the following snippet:
    <div class="ck-widget bs_grid" contenteditable="false">
        <div class="ck-widget row" data-row-none="12_12" data-row-sm="none"
            data-row-md="equal_equal" data-row-lg="none" data-row-xl="none"
            data-row-xxl="none" contenteditable="false">
            <div class="col-12 col-md">
                <p>
                    Column 1 content
                </p>
            </div>
            <div class="col-12 col-md">
                <p>
                    Column 2 content
                </p>
                <div>
                    <p>
                        Should appear inside the second column
                    </p>
                </div>
            </div>
        </div>
    </div>
    
  8. Switch back to wysiwyg mode
  9. Notice how your div is appearing as a third column
  10. Switch to source editing mode again to see how the structure has changed
    Result:
    <div class="ck-widget ck-widget bs_grid" contenteditable="false">
        <div class="ck-widget ck-widget row" data-row-none="12_12"
            data-row-sm="none" data-row-md="equal_equal" data-row-lg="none"
            data-row-xl="none" data-row-xxl="none" contenteditable="false">
            <div class="col-12 col-md">
                <p>
                    Column 1 content
                </p>
            </div>
            <div class="col-12 col-md">
                <p>
                    Column 2 content
                </p>
            </div>
            <div class="col-12 col-md">
                <p>
                    Should appear inside the second column
                </p>
            </div>
        </div>
    </div>
    

Proposed resolution

The root cause of the issue is targeting all div tags without specifying a specific class for example while upcasting.

To fix this we can add bs_grid_col class when creating a grid as well as when upcasting to ensure we don't upcast other elements into bsGridCol unintentionally.

After fix:

We also need to consider existing content that doesn't have bs_grid_col class, not sure how to cover that without updating the database.

πŸ› Bug report
Status

Needs work

Version

2.0

Component

Code

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.69.0 2024