Opened 33 hours ago
Last modified 15 hours ago
#66379 new defect (bug)
Classic Editor: Switching from Text to Visual mode restructures HTML lists based on cursor position
| Reported by: | dedri | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Awaiting Review |
| Component: | Editor | Version: | |
| Severity: | normal | Keywords: | has-patch has-unit-tests |
| Cc: | Focuses: |
Description
Since updating to WordPress 7.1.3, I've encountered a reproducible issue with bulleted lists in the Classic Editor.
Simply placing the cursor at the end of a list item in Text mode, without making any changes to the HTML, causes WordPress to restructure the list when switching back to Visual mode.
All list items preceding the cursor position become nested inside an additional <ul>, wrapped in a new <li style="list-style-type: none;"> element.
This results in unwanted indentation and changes to otherwise valid HTML.
Steps to reproduce
1 Create a new post using Classic Editor.
2 In Visual mode, create a bulleted list containing five items: A, B, C, D and E.
3 Switch to Text mode.
4 Place the cursor at the end of the <li>D</li> line without typing or modifying anything.
5 Switch back to Visual mode.
Actual result:
Items A, B and C become indented as a nested list. The editor inserts an additional parent list item with style="list-style-type: none;" and separates the remaining items into another list.
Expected result:
The HTML and visual formatting should remain unchanged because no edits were made.
Additional observations
The point where the list splits follows the cursor position.
Switching between Text and Visual modes without repositioning the cursor does not cause the problem.
The issue is reproducible in both Chrome and Microsoft Edge.
The original HTML is valid.
The issue appeared following recent PHP and WordPress updates.
Environment
WordPress: 7.1.3
Classic Editor plugin: 1.7.0
PHP: 8.3.36
Hosting: DreamHost
Theme: Genesis child theme
Browsers tested: Chrome and Microsoft Edge
Related ticket
This behaviour appears similar to WordPress Core Trac ticket #29643, which documents unwanted nested lists and insertion of <li style="list-style-type: none;"> when switching between editing modes.
https://core.trac.wordpress.org/ticket/29643
Attachments
Three screenshots demonstrating the original list, the resulting indentation in Visual mode, and the modified HTML in Text mode.
Attachments (3)
Change History (4)
This ticket was mentioned in PR #14883 on WordPress/wordpress-develop by @sourav08.
15 hours ago
#1
- Keywords has-patch has-unit-tests added
Description
Fixes https://core.trac.wordpress.org/ticket/66379.
Switching from Text to Visual mode in the Classic Editor with the cursor positioned immediately after a closing </li> tag causes TinyMCE to restructure the list unexpectedly.
This happens because the editor inserts a temporary selection bookmark directly inside the list, creating an invalid HTML structure. TinyMCE then normalizes the markup by nesting preceding list items inside an additional <li style="list-style-type: none;"> element, resulting in unwanted indentation and changes to the original list.
Changes
- Adjusted both selection endpoints to ensure bookmarks positioned after
</li>tags or their trailing whitespace are inserted inside the preceding list item. - Prevented TinyMCE from receiving invalid list structures during editor switching.
- Preserved the original list markup and cursor selection when switching between Text and Visual modes.
Testing
- Added regression tests covering ordered, unordered, and nested lists, whitespace variations, uppercase tags, list item attributes, and selection ranges.
- Confirmed all 41 assertions pass with the fix, while 27 assertions fail with the original implementation.
- Verified the behavior with WordPress's TinyMCE plugin and
wpautopenabled. - Confirmed JavaScript lint checks pass.
Use of AI Tools
AI assistance: Yes
Tool(s): ChatGPT
Model(s): GPT-6
Used for: Assistance with investigation and implementation suggestions. Final implementation and regression tests were reviewed and verified manually.
---
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See [https://make.wordpress.org/core/handbook/contribute/git/github-pull-requests-for-code-review/ [GitHub Pull Requests for Code Review]](https://make.wordpress.org/core/handbook/contribute/git/github-pull-requests-for-code-review/) in the Core Handbook for more details.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
1 List before moving cursor