Conversation
Browsers treat plaintext-only as an editing host. The jsdom polyfill only recognized true/empty, so type() never inserted text.
snowystinger
left a comment
There was a problem hiding this comment.
Thanks for the PR, can you provide a test for
Chained closest() can return a farther true ancestor instead of a nearer plaintext-only host
I imagine it'd be something like this setup
<div contenteditable="">
<div contenteditable="true">
<span>
It'd also be good to include a paste test for "plaintext-only".
Enter on plaintext-only still uses insertParagraph (same as contenteditable="true"). No plaintext-only special case for insertLineBreak. Can add that as a follow-up.
I don't think this should be follow-up, code will start going through here as soon as it's released, so we should have this complete before releasing. I can take a look later if you don't have time.
Add the nearest-editing-host cases for the ancestor walk that replaced the
chained closest() calls. The contenteditable="true" case fails on the old
implementation too: closest('[contenteditable=""]') matched a farther
ancestor before the nearer host was considered.
Add a paste test covering contenteditable="true" and "plaintext-only".
A plaintext-only editing host has no paragraphs to break, so Enter is a line break. editContenteditable inserts "\n" for either inputType, so this corrects the reported type rather than the resulting content.
|
Pushed the tests and the Enter change in 1c33ed9. The chained For Enter I went with |
Ah, didn't realise it was a difference between browsers. Does the spec say anything more official? The other way would've tried to insert a |
What
Treat
contenteditable="plaintext-only"as an editing host souser.type()and the other edit/focus paths that share the same checks insert text the same way they already do forcontenteditable="true"/contenteditable.Fixes #1197.
Why
The HTML spec lists
plaintext-onlyas acontenteditablekeyword. An editing host is an element in the true or plaintext-only state. jsdom does not implementHTMLElement.isContentEditable, and this library's polyfill only treatedtrueand the empty attribute as editable, sotype()clicked a non-focusable node and never dispatched input.How
isContentEditable()with theplaintext-onlyattribute value.[contenteditable="plaintext-only"]inFOCUSABLE_SELECTORso click/tab focus the host.getContentEditable()by walking ancestors withisContentEditable()so the allow-list lives in one place.Walk with
isContentEditableinstead of adding a thirdelement.closest('[contenteditable="plaintext-only"]'). Chainedclosest()returned a farther ancestor instead of the nearest editing host, which affectedcontenteditable="true"as well asplaintext-only. Both are covered by tests.Enter on plaintext-only reports
insertLineBreak. A plaintext-only host has no paragraphs to break, andeditContenteditableinserts\nfor either inputType, so this corrects the reported type rather than the content.Checklist