Page MenuHomePhabricator

Broken HTML output for block-tags in links
Closed, DuplicatePublic

Description

The output for "Media link with nasty text\nfixme: doBlockLevels won't wrap this in a paragraph because it contains a div" has a <div> inside a <a>-tag. All looks good, except when the HTML is parsed back, the DOM breaks up.

See this session output:

[subbu@earth tests] echo "[[Foo|<div>boo</div>]]" | node parse --normalize
<p><a href="Foo" title="Foo">
<div>boo</div>
</a></p>

[subbu@earth tests] node
> var DU = require('../lib/mediawiki.DOMUtils.js').DOMUtils
undefined
> DU.parseHTML('<p><a href="Foo" title="Foo">\n<div>boo</div>\n</a></p>').outerHTML
'<html><head></head><body><p><a href="Foo" title="Foo">\n</a></p><div><a href="Foo" title="Foo">boo</a></div><a href="Foo" title="Foo">\n</a><p></p></body></html>'

So, we need to figure out what to emit for this kind of wikitext and whether this is domino-specific or breaks in all browsers.

Event Timeline

ssastry raised the priority of this task from to Needs Triage.
ssastry updated the task description. (Show Details)
ssastry subscribed.
ssastry triaged this task as Medium priority.Feb 17 2015, 7:48 PM
ssastry added a project: Parsoid.
ssastry set Security to None.

PHP emits:

$ echo '[[Foo|<div>boo</div>]]' | php maintenance/parse.php 
parse.php: warning: reading wikitext from STDIN. Press CTRL+D to parse.

<p><a href="/~cananian/mediawiki/index.php/Foo" title="Foo">&lt;div&gt;boo&lt;/div&gt;</a>
</p>

So I don't think the <div> is the problem, per se.

This may be a domino bug .. When I create a HTML file with that snippet and open it and inspect the <a> tag .. the <div> is properly nested there.

This may be a domino bug .. When I create a HTML file with that snippet and open it and inspect the <a> tag .. the <div> is properly nested there.

I think you need to recheck that. Chrome and Firefox produce the same output as domino, as far as I can tell.

http://www.w3.org/TR/html5/text-level-semantics.html#the-a-element

"The a element may be wrapped around entire paragraphs, lists, tables, and so forth, even entire sections, so long as there is no interactive content within (e.g. buttons or other links)."

This comment was removed by cscott.

I think I might be misremembering the spec here. Chrome seems to parse this okay:

d = document.createElement('div')
d.innerHTML = '<a><div>foo</div></a>'
"<a><div>foo</div></a>"
d.outerHTML
"<div><a><div>foo</div></a></div>"
d.innerHTML = '<a><div>foo<a>bar</a></div></a>'
"<a><div>foo<a>bar</a></div></a>"
d.outerHTML
"<div><a></a><div><a>foo</a><a>bar</a></div></div>"

Domino also parses this correctly:

> var domino = require('domino');
undefined
> document = domino.createDocument(); 1;
1
> d = document.createElement('div'); 1;
1
> d.innerHTML = '<a><div>foo</div></a>';
'<a><div>foo</div></a>'
> d.outerHTML
'<div><a><div>foo</div></a></div>'

Oh, it's actually the <div>-inside-<p> which is causing the problem. On chrome:

> document.body.innerHTML = '<p><a><div>foo</div></a></p>';
< "<p><a><div>foo</div></a></p>"
> document.body.outerHTML
< "<body><p><a></a></p><div><a>foo</a></div><p></p></body>"
> document.body.innerHTML = '<div><a><div>foo</div></a></div>';
< "<div><a><div>foo</div></a></div>"
> document.body.outerHTML
< "<body><div><a><div>foo</div></a></div></body>"

(Domino agrees with this.)

You don't even need the a-tag

> DU.parseHTML('<p><div>BOO!</div></p>').body.outerHTML
'<body><p></p><div>BOO!</div><p></p></body>'

Ah, the spec says that the content model inside a <p> is "phrasing content", but the content model inside a <div> is "flow content". And that <div> is an example of flow content. So no <div> inside a <p>.

So it appears that PHP is correct: you need to &lt;-escape the <div> if you are inside a paragraph.

Ok, to summarize this long comment-thread and IRC conversation:

Our paragraph-wrapper doesn't add <p> tags around any block tags (html4 terminology). So, it shouldn't normally be adding the p-wrapper around the <div> tag anyway. However, the presence of a link around the <div> seems to be tripping it up somehow ...

This trace output shows the problem .. We are parsing link content separately and wrapping it in a dom-fragment which loses context about any embedded "block tags" and p-wrapper is therefore blind to its presence.

[subbu@earth lib] echo "[[Foo|<div>boo</div>]]" | node parse --fetchConfig false --trace tsp
2-[TSP]        | {"type":"TagTk","name":"div","attribs":[],"dataAttribs":{"tsr":[6,11],"stx":"html"}}
2-[TSP]        | "boo"
2-[TSP]        | {"type":"EndTagTk","name":"div","attribs":[],"dataAttribs":{"tsr":[14,20],"stx":"html"}}
2-[TSP]        | {"type":"EOFTk"}
0-[TSP]        | {"type":"TagTk","name":"a","attribs":[{"k":"rel","v":"mw:WikiLink"},{"k":"href","v":"./Foo"},{"k":"title","v":"Foo"}],"dataAttribs":{"tsr":[0,22],"stx":"piped","a":{"href":"./Foo"},"sa":{"href":"Foo"}}}
0-[TSP]        | {"type":"TagTk","name":"span","attribs":[{"k":"typeof","v":"mw:DOMFragment"},{"k":"about","v":"#mwt1"}],"dataAttribs":{"stx":"html","dsr":[6,20,5,6],"html":"<div data-parsoid=\"{&quot;stx&quot;:&quot;html&quot;,&quot;dsr&quot;:[6,20,5,6]}\">boo</div>"}}
0-[TSP]        | {"type":"EndTagTk","name":"span","attribs":[{"k":"about","v":"#mwt1"}],"dataAttribs":{"stx":"html"}}
0-[TSP]        | {"type":"EndTagTk","name":"a","attribs":[],"dataAttribs":{}}
0-[TSP]        | {"type":"NlTk","dataAttribs":{"tsr":[22,23]}}
0-[TSP]        | {"type":"EOFTk"}

Change 246840 had a related patch set uploaded (by Cscott):
WIP: T89753: no <div> in link captions.

https://gerrit.wikimedia.org/r/246840

Change 246840 abandoned by Subramanya Sastry:
WIP: T89753: no <div> in link captions.

Reason:
Old patch that does nothing yet.

https://gerrit.wikimedia.org/r/246840