The Mozilla HTML editor creates a bunch of <br> elements for historical reasons. One of the most irritating situations is when you expect a <p> but get a <br>… for example in this ContentEditable demo:
Go ahead, edit away!
Here's a typical paragraph element
- and now a list
- with only
- three items
[Return] in paragraphs
When editing a “contentEditable” element in Firefox, pressing [Return] in a paragraph splits the paragraph: if you press [Return] at the end of a paragraph, a new paragraph is created.
When editing HTML documents in comm-central apps (Thunderbird HTML messages, SeaMonkey Composer documents) the behavior is slightly different:
- pressing [Return] once at the end of a paragraph creates a <br> element;
- pressing [Return] twice at the end of a paragraph creates a <p> element.
The reason is, the editor component has a returnInParagraphCreatesNewParagraph property which is true by default on Firefox, but not on Thunderbird and SeaMonkey. You can set this property to false on Firefox (contentEditable) with:
document.execCommand("insertBrOnReturn", false, "true")
Note that the insertBrOnReturn command is Mozilla-specific.
SeaMonkey and Thunderbird parse the editor.CR_creates_new_p preference (false by default) and apply its value to editor.returnInParagraphCreatesNewParagraph. You can change the value of editor.CR_creates_new_p in “about:config” if you prefer the Firefox behavior (and you probably do).
A trickier case in Firefox is when the active editing host is an inline element:
Try to
press [Return] here
and complain.
<p> Try to
<span contenteditable>press [Return] here</span>
and complain. </p>
As Firefox always tries to create a new paragraph in such situations, and since the editing host is a <span>, nothing happens when [Return] is pressed. This should be fixed with bug 460740.
Of course, in all cases a [Shift+Return] creates a <br>, which is fine.
[Return] in headers and lists
With current versions of Firefox (5, Beta, Aurora):
- pressing [Return] at the end of a header element (<h[1…6]>) creates two line breaks (<br>), though most users expect a new paragraph.
- pressing [Return] once at the end of a list element (<li> or <dt>) creates a new list item (<li> or <dd> respectively); pressing [Return] twice splits the list if necessary and creates a line break, though again, most users expect a new paragraph.
Note that there’s no equivalent to the editor.returnInParagraphCreatesNewParagraph property for headers or lists: pressing [Return] at the end of list or header element never inserts any <br> within this element.
There’s no spec that describe the expected behavior of the HTML editor in such case. I think the only intuitive rule would be to create a new block element (<p>) when we’re getting out of another block element with [Return]. That’s what Chromium and Opera do (and probably IE and Safari as well), and that’s what I’ve done in bug 449243. You can test this behavior in Firefox Nightly.
Note: when editing a list in Thunderbird or SeaMonkey Composer with this patch, if you click on the “list” toolbar button the list content will be converted to body text, not to a paragraph. I’ll have to work on that in order to preserve the consistency.
Consistency: <p> everywhere?
Again, there’s no spec for the behavior of the [Return] key in an editable document fragment but we can assume that the [Return] key action should be as consistent as possible across the different editing situations. That’s the idea behind the new behavior of the [Return] key in headers and lists.
I don’t think the editor should force all text to be enclosed in paragraphs, though. As an example, in this editable <div> there’s no HTML structure so I expect [Return] to create <br>:
Type your text here!
<div contenteditable>
Type your text here!
</div>
When [Return] is pressed at the end of the line of text, I expect to get a <br> (FWIW, that’s what Chromium does, too). I don’t expect [Return] to turn the text into a paragraph, then create another paragraph. If I wanted all text to be enclosed in paragraphs I could just use this instead:
<div contenteditable>
<p> Type your text here! </p>
</div>
I think comm-central apps (Thunderbird, SeaMonkey…) might want to adapt to this new behavior: since HTML messages in Thunderbird and documents in SeaMonkey Composer are structured HTML documents, these apps could initialize the editor not on “about:blank” as they do now, but on an empty HTML document containing a paragraph. In this case, changing the default value of editor.CR_creates_new_p would make sense.
I’m pretty sure that’s what SeaMonkey Composer users want, but I don’t know if this applies to Thunderbird. In fact, Thunderbird might even prefer creating <br> instead of <p> when [Return] is pressed… if that’s the case, please let me know.
[update 2011-07-28] Aryeh Gregor (WhatWG) has just published a preliminary draft of the HTML Editing APIs specification. Thanks Anthony for the link!