Affects Version/s: 3.5.2, 3.7, 3.7.1
Fix Version/s: None
Component/s: HTML Editor (Atto)
Affected Branches:MOODLE_35_STABLE, MOODLE_37_STABLE
The Atto Editor produces invalid HTML when nesting lists using the toolbar buttons "Ordered List", "Unordered list", and "Indent". In most cases this is not apparent because web browsers render the invalid HTML correctly. However, when creating/editing Forum posts with nested lists of different types (ordered/unordered), the HTML is munged and the nesting is broken.
Log in to the Moodle sandbox demo (https://demo.moodle.net/) as "teacher".
My First Course > New forum > Add new topic.
Type something for the subject.
In the Message box:
- type "foo"
- click the "Ordered list" button
- press Enter, type "bar"
- click the "Show more buttons" (arrow) button, "Indent", then "Unordered list"
- should look like screenshot 1
Post to forum.
EXPECT: The unordered list should be nested inside the ordered list as displayed while editing.
ACTUAL: The unordered list is after and outside the ordered list, see screenshot 2.
If I switch to HTML mode while editing using the "</>" button, the content is
When I edit the message after posting, the content is
(note how the </ol> tag moved, breaking the nesting)
The original HTML is invalid according to the W3C validator (https://validator.w3.org) because <ul> cannot be directly inside <ol>. It should be
The root cause appears to be document.execCommand('indent'), which produces the invalid HTML in most browsers. There is a bug report against the HTML5 spec which explains this and requests that the nesting is to be considered valid, but it was rejected: https://www.w3.org/Bugs/Public/show_bug.cgi?id=12609.
The munging in Forum posts appears to be because the invalid HTML is handled badly by HTML Purifier. The TinyMCE bugs above mention this and link to http://htmlpurifier.org/phorum/read.php?3,5451.
It appears that HTML Purifier can handle the invalid HTML correctly since version 4.4 (released 2012), but only in some configurations. On the live demo (http://htmlpurifier.org/demo.php) the output has incorrect nesting like on Moodle, but the following program produces the correct nesting with HTML Purifier 4.4 through 4.10:
$config = HTMLPurifier_Config::createDefault();
$purifier = new HTMLPurifier($config);
$clean_html = $purifier->purify("<ol><li>foo</li><ul><li>bar<br></li></ul></ol>");
// output: <ol><li>foo<ul><li>bar<br /></li></ul></li></ol>